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
48 changes: 47 additions & 1 deletion src/Builders/PromptBuilder.php
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@
use WordPress\AiClient\Events\BeforeGenerateResultEvent;
use WordPress\AiClient\Files\DTO\File;
use WordPress\AiClient\Files\Enums\FileTypeEnum;
use WordPress\AiClient\Files\Enums\MediaOrientationEnum;
use WordPress\AiClient\Messages\DTO\Message;
use WordPress\AiClient\Messages\DTO\MessagePart;
use WordPress\AiClient\Messages\DTO\UserMessage;
Expand Down Expand Up @@ -459,7 +460,7 @@ public function usingTopK(int $topK): self
*/
public function usingStopSequences(string ...$stopSequences): self
{
$this->modelConfig->setCustomOption('stopSequences', $stopSequences);
$this->modelConfig->setStopSequences($stopSequences);
return $this;
}

Expand Down Expand Up @@ -627,6 +628,51 @@ public function asOutputFileType(FileTypeEnum $fileType): self
return $this;
}

/**
* Sets the output media orientation.
*
* @since n.e.x.t
*
* @param MediaOrientationEnum $orientation The output media orientation.
* @return self
*/
public function asOutputMediaOrientation(MediaOrientationEnum $orientation): self
{
$this->modelConfig->setOutputMediaOrientation($orientation);
return $this;
}

/**
* Sets the output media aspect ratio.
*
* If set, this supersedes the output media orientation, as it is a more
* specific configuration.
*
* @since n.e.x.t
*
* @param string $aspectRatio The aspect ratio (e.g. "16:9", "3:2").
* @return self
*/
public function asOutputMediaAspectRatio(string $aspectRatio): self
{
$this->modelConfig->setOutputMediaAspectRatio($aspectRatio);
return $this;
}

/**
* Sets the output speech voice.
*
* @since n.e.x.t
*
* @param string $voice The output speech voice.
* @return self
*/
public function asOutputSpeechVoice(string $voice): self
{
$this->modelConfig->setOutputSpeechVoice($voice);
return $this;
}

/**
* Configures the prompt for JSON response output.
*
Expand Down
126 changes: 116 additions & 10 deletions tests/unit/Builders/PromptBuilderTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@
use WordPress\AiClient\Builders\PromptBuilder;
use WordPress\AiClient\Files\DTO\File;
use WordPress\AiClient\Files\Enums\FileTypeEnum;
use WordPress\AiClient\Files\Enums\MediaOrientationEnum;
use WordPress\AiClient\Messages\DTO\Message;
use WordPress\AiClient\Messages\DTO\MessagePart;
use WordPress\AiClient\Messages\DTO\ModelMessage;
Expand Down Expand Up @@ -1055,19 +1056,17 @@ public function testUsingModelConfigWithCustomOptions(): void
$this->assertArrayHasKey('otherOption', $customOptions);
$this->assertEquals('value', $customOptions['otherOption']);

// Now set a builder value that overrides one of the custom options
// Now set stop sequences via the dedicated method
$builder->usingStopSequences('STOP');

// Get the config again
$mergedConfig = $configProperty->getValue($builder);
$customOptions = $mergedConfig->getCustomOptions();

// Assert builder's stop sequences override the config's
$this->assertArrayHasKey('stopSequences', $customOptions);
$this->assertIsArray($customOptions['stopSequences']);
$this->assertEquals(['STOP'], $customOptions['stopSequences']);
// Assert builder's stop sequences are set on the dedicated property
$this->assertEquals(['STOP'], $mergedConfig->getStopSequences());

// Assert other custom options are still preserved
// Assert custom options are still preserved
$customOptions = $mergedConfig->getCustomOptions();
$this->assertArrayHasKey('otherOption', $customOptions);
$this->assertEquals('value', $customOptions['otherOption']);
}
Expand Down Expand Up @@ -1215,9 +1214,7 @@ public function testUsingStopSequences(): void
/** @var ModelConfig $config */
$config = $configProperty->getValue($builder);

$customOptions = $config->getCustomOptions();
$this->assertArrayHasKey('stopSequences', $customOptions);
$this->assertEquals(['STOP', 'END', '###'], $customOptions['stopSequences']);
$this->assertEquals(['STOP', 'END', '###'], $config->getStopSequences());
}

/**
Expand Down Expand Up @@ -3605,4 +3602,113 @@ public function testCloneWorksWithNullRequestOptions(): void

$this->assertNull($optionsProperty->getValue($cloned));
}

/**
* Tests asOutputMediaOrientation method.
*
* @return void
*/
public function testAsOutputMediaOrientation(): void
{
$builder = new PromptBuilder($this->registry);
$result = $builder->asOutputMediaOrientation(MediaOrientationEnum::landscape());

$this->assertSame($builder, $result);

$reflection = new \ReflectionClass($builder);
$configProperty = $reflection->getProperty('modelConfig');
$configProperty->setAccessible(true);
/** @var ModelConfig $config */
$config = $configProperty->getValue($builder);

$outputMediaOrientation = $config->getOutputMediaOrientation();
$this->assertNotNull($outputMediaOrientation);
$this->assertTrue($outputMediaOrientation->isLandscape());
}

/**
* Tests asOutputMediaOrientation method with portrait orientation.
*
* @return void
*/
public function testAsOutputMediaOrientationWithPortrait(): void
{
$builder = new PromptBuilder($this->registry);
$result = $builder->asOutputMediaOrientation(MediaOrientationEnum::portrait());

$this->assertSame($builder, $result);

$reflection = new \ReflectionClass($builder);
$configProperty = $reflection->getProperty('modelConfig');
$configProperty->setAccessible(true);
/** @var ModelConfig $config */
$config = $configProperty->getValue($builder);

$outputMediaOrientation = $config->getOutputMediaOrientation();
$this->assertNotNull($outputMediaOrientation);
$this->assertTrue($outputMediaOrientation->isPortrait());
}

/**
* Tests asOutputMediaAspectRatio method.
*
* @return void
*/
public function testAsOutputMediaAspectRatio(): void
{
$builder = new PromptBuilder($this->registry);
$result = $builder->asOutputMediaAspectRatio('16:9');

$this->assertSame($builder, $result);

$reflection = new \ReflectionClass($builder);
$configProperty = $reflection->getProperty('modelConfig');
$configProperty->setAccessible(true);
/** @var ModelConfig $config */
$config = $configProperty->getValue($builder);

$this->assertEquals('16:9', $config->getOutputMediaAspectRatio());
}

/**
* Tests asOutputSpeechVoice method.
*
* @return void
*/
public function testAsOutputSpeechVoice(): void
{
$builder = new PromptBuilder($this->registry);
$result = $builder->asOutputSpeechVoice('alloy');

$this->assertSame($builder, $result);

$reflection = new \ReflectionClass($builder);
$configProperty = $reflection->getProperty('modelConfig');
$configProperty->setAccessible(true);
/** @var ModelConfig $config */
$config = $configProperty->getValue($builder);

$this->assertEquals('alloy', $config->getOutputSpeechVoice());
}

/**
* Tests usingStopSequences sets the dedicated property.
*
* @return void
*/
public function testUsingStopSequencesSetsProperty(): void
{
$builder = new PromptBuilder($this->registry);
$result = $builder->usingStopSequences('STOP', 'END');

$this->assertSame($builder, $result);

$reflection = new \ReflectionClass($builder);
$configProperty = $reflection->getProperty('modelConfig');
$configProperty->setAccessible(true);
/** @var ModelConfig $config */
$config = $configProperty->getValue($builder);

$this->assertEquals(['STOP', 'END'], $config->getStopSequences());
}
}