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
24 changes: 24 additions & 0 deletions src/AiClient.php
Original file line number Diff line number Diff line change
Expand Up @@ -362,6 +362,30 @@ public static function generateSpeechResult(
return self::getConfiguredPromptBuilder($prompt, $modelOrConfig, $registry)->generateSpeechResult();
}

/**
* Generates sound using the traditional API approach.
*
* @since 1.4.0
*
* @param Prompt $prompt The prompt content.
* @param ModelInterface|ModelConfig|null $modelOrConfig Optional specific model to use,
* or model configuration for auto-discovery,
* or null for defaults.
* @param ProviderRegistry|null $registry Optional custom registry. If null, uses default.
* @return GenerativeAiResult The generation result.
*
* @throws \InvalidArgumentException If the prompt format is invalid.
* @throws \RuntimeException If no suitable model is found.
*/
public static function generateSoundResult(
$prompt,
$modelOrConfig = null,
?ProviderRegistry $registry = null
): GenerativeAiResult {
self::validateModelOrConfigParameter($modelOrConfig);
return self::getConfiguredPromptBuilder($prompt, $modelOrConfig, $registry)->generateSoundResult();
}

/**
* Generates a video using the traditional API approach.
*
Expand Down
79 changes: 79 additions & 0 deletions src/Builders/PromptBuilder.php
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@
use WordPress\AiClient\Providers\Models\DTO\ModelRequirements;
use WordPress\AiClient\Providers\Models\Enums\CapabilityEnum;
use WordPress\AiClient\Providers\Models\ImageGeneration\Contracts\ImageGenerationModelInterface;
use WordPress\AiClient\Providers\Models\SoundGeneration\Contracts\SoundGenerationModelInterface;
use WordPress\AiClient\Providers\Models\SpeechGeneration\Contracts\SpeechGenerationModelInterface;
use WordPress\AiClient\Providers\Models\TextGeneration\Contracts\TextGenerationModelInterface;
use WordPress\AiClient\Providers\Models\TextToSpeechConversion\Contracts\TextToSpeechConversionModelInterface;
Expand Down Expand Up @@ -758,6 +759,9 @@ private function inferCapabilityFromModelInterfaces(ModelInterface $model): ?Cap
if ($model instanceof SpeechGenerationModelInterface) {
return CapabilityEnum::speechGeneration();
}
if ($model instanceof SoundGenerationModelInterface) {
return CapabilityEnum::soundGeneration();
}
if ($model instanceof VideoGenerationModelInterface) {
return CapabilityEnum::videoGeneration();
}
Expand Down Expand Up @@ -871,6 +875,18 @@ public function isSupportedForSpeechGeneration(): bool
return $this->isSupported(CapabilityEnum::speechGeneration());
}

/**
* Checks if the prompt is supported for sound generation.
*
* @since 1.4.0
*
* @return bool True if sound generation is supported.
*/
public function isSupportedForSoundGeneration(): bool
{
return $this->isSupported(CapabilityEnum::soundGeneration());
}

/**
* Checks if the prompt is supported for music generation.
*
Expand Down Expand Up @@ -1012,6 +1028,18 @@ private function executeModelGeneration(
return $model->generateSpeechResult($messages);
}

if ($capability->isSoundGeneration()) {
if (!$model instanceof SoundGenerationModelInterface) {
throw new RuntimeException(
sprintf(
'Model "%s" does not support sound generation.',
$model->metadata()->getId()
)
);
}
return $model->generateSoundResult($messages);
}

if ($capability->isVideoGeneration()) {
if (!$model instanceof VideoGenerationModelInterface) {
throw new RuntimeException(
Expand Down Expand Up @@ -1102,6 +1130,24 @@ public function convertTextToSpeechResult(): GenerativeAiResult
return $this->generateResult(CapabilityEnum::textToSpeechConversion());
}

/**
* Generates a sound result from the prompt.
*
* @since 1.4.0
*
* @return GenerativeAiResult The generated result containing sound audio candidates.
* @throws InvalidArgumentException If the prompt or model validation fails.
* @throws RuntimeException If the model doesn't support sound generation.
*/
public function generateSoundResult(): GenerativeAiResult
{
// Include audio in output modalities
$this->includeOutputModalities(ModalityEnum::audio());

// Generate and return the result with sound generation capability
return $this->generateResult(CapabilityEnum::soundGeneration());
}

/**
* Generates a video result from the prompt.
*
Expand Down Expand Up @@ -1251,6 +1297,39 @@ public function generateSpeeches(?int $candidateCount = null): array
return $this->generateSpeechResult()->toFiles();
}

/**
* Generates sound from the prompt.
*
* @since 1.4.0
*
* @return File The generated sound audio file.
* @throws InvalidArgumentException If the prompt or model validation fails.
* @throws RuntimeException If no audio is generated.
*/
public function generateSound(): File
{
return $this->generateSoundResult()->toFile();
}

/**
* Generates multiple sound outputs from the prompt.
*
* @since 1.4.0
*
* @param int|null $candidateCount The number of sound outputs to generate.
* @return list<File> The generated sound audio files.
* @throws InvalidArgumentException If the prompt or model validation fails.
* @throws RuntimeException If no audio is generated.
*/
public function generateSounds(?int $candidateCount = null): array
{
if ($candidateCount !== null) {
$this->usingCandidateCount($candidateCount);
}

return $this->generateSoundResult()->toFiles();
}

/**
* Generates a video from the prompt.
*
Expand Down
7 changes: 7 additions & 0 deletions src/Providers/Models/Enums/CapabilityEnum.php
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@
* @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 soundGeneration() Creates an instance for SOUND_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.
Expand All @@ -24,6 +25,7 @@
* @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 isSoundGeneration() Checks if the capability is SOUND_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.
Expand Down Expand Up @@ -55,6 +57,11 @@ class CapabilityEnum extends AbstractEnum
*/
public const MUSIC_GENERATION = 'music_generation';

/**
* Sound generation capability.
*/
public const SOUND_GENERATION = 'sound_generation';

/**
* Video generation capability.
*/
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
<?php

declare(strict_types=1);

namespace WordPress\AiClient\Providers\Models\SoundGeneration\Contracts;

use WordPress\AiClient\Messages\DTO\Message;
use WordPress\AiClient\Results\DTO\GenerativeAiResult;

/**
* Interface for models that support sound generation.
*
* Provides synchronous methods for generating sounds from prompts.
*
* @since 1.4.0
*/
interface SoundGenerationModelInterface
{
/**
* Generates sound from a prompt.
*
* @since 1.4.0
*
* @param list<Message> $prompt Array of messages containing the sound generation prompt.
* @return GenerativeAiResult Result containing generated sound audio.
*/
public function generateSoundResult(array $prompt): GenerativeAiResult;
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
<?php

declare(strict_types=1);

namespace WordPress\AiClient\Providers\Models\SoundGeneration\Contracts;

use WordPress\AiClient\Messages\DTO\Message;
use WordPress\AiClient\Operations\DTO\GenerativeAiOperation;

/**
* Interface for models that support asynchronous sound generation operations.
*
* Provides methods for initiating long-running sound generation tasks.
*
* @since 1.4.0
*/
interface SoundGenerationOperationModelInterface
{
/**
* Creates a sound generation operation.
*
* @since 1.4.0
*
* @param list<Message> $prompt Array of messages containing the sound generation prompt.
* @return GenerativeAiOperation The initiated sound generation operation.
*/
public function generateSoundOperation(array $prompt): GenerativeAiOperation;
}
3 changes: 3 additions & 0 deletions tests/unit/AiClientTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -514,6 +514,7 @@ public function testTraditionalMethodsAcceptModelConfig(): void
'generateImageResult',
'convertTextToSpeechResult',
'generateSpeechResult',
'generateSoundResult',
'generateVideoResult'
];

Expand Down Expand Up @@ -573,6 +574,7 @@ public function aiClientMethodsProvider(): array
'generateImageResult' => ['generateImageResult'],
'convertTextToSpeechResult' => ['convertTextToSpeechResult'],
'generateSpeechResult' => ['generateSpeechResult'],
'generateSoundResult' => ['generateSoundResult'],
'generateVideoResult' => ['generateVideoResult'],
];
}
Expand Down Expand Up @@ -705,6 +707,7 @@ public function testModelConfigPassedToAllMethods(): void
'generateImageResult',
'convertTextToSpeechResult',
'generateSpeechResult',
'generateSoundResult',
'generateVideoResult'
];

Expand Down
Loading
Loading