Skip to content

Commit 70e5e22

Browse files
JasonTheAdamsfelixarntzJasonTheAdams
authored
Merge pull request #134 from WordPress/enhancement/is-supported-public
Co-authored-by: felixarntz <[email protected]> Co-authored-by: JasonTheAdams <[email protected]>
2 parents 1e7ec2e + 1720664 commit 70e5e22

File tree

5 files changed

+144
-12
lines changed

5 files changed

+144
-12
lines changed

docs/ARCHITECTURE.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -340,6 +340,7 @@ direction LR
340340
+convertTextToSpeeches(?int $candidateCount) File[]
341341
+generateSpeech() File
342342
+generateSpeeches(?int $candidateCount) File[]
343+
+isSupported(?CapabilityEnum $capability) bool
343344
+isSupportedForTextGeneration() bool
344345
+isSupportedForImageGeneration() bool
345346
+isSupportedForTextToSpeechConversion() bool

src/Builders/PromptBuilder.php

Lines changed: 19 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -492,7 +492,7 @@ public function usingWebSearch(WebSearch $webSearch): self
492492
/**
493493
* Sets the request options for HTTP transport.
494494
*
495-
* @since n.e.x.t
495+
* @since 0.3.0
496496
*
497497
* @param RequestOptions $requestOptions The request options.
498498
* @return self
@@ -676,19 +676,31 @@ private function inferCapabilityFromModelInterfaces(ModelInterface $model): ?Cap
676676
* Checks if the current prompt is supported by the selected model.
677677
*
678678
* @since 0.1.0
679+
* @since 0.3.0 Method visibility changed to public.
679680
*
680-
* @param CapabilityEnum|null $intendedCapability Optional capability to check support for.
681+
* @param CapabilityEnum|null $capability Optional capability to check support for.
681682
* @return bool True if supported, false otherwise.
682683
*/
683-
private function isSupported(?CapabilityEnum $intendedCapability = null): bool
684+
public function isSupported(?CapabilityEnum $capability = null): bool
684685
{
685686
// If no intended capability provided, infer from output modalities
686-
if ($intendedCapability === null) {
687-
$intendedCapability = $this->inferCapabilityFromOutputModalities();
687+
if ($capability === null) {
688+
// First try to infer from a specific model if one is set
689+
if ($this->model !== null) {
690+
$inferredCapability = $this->inferCapabilityFromModelInterfaces($this->model);
691+
if ($inferredCapability !== null) {
692+
$capability = $inferredCapability;
693+
}
694+
}
695+
696+
// If still no capability, infer from output modalities
697+
if ($capability === null) {
698+
$capability = $this->inferCapabilityFromOutputModalities();
699+
}
688700
}
689701

690702
// Build requirements with the specified capability
691-
$requirements = ModelRequirements::fromPromptData($intendedCapability, $this->messages, $this->modelConfig);
703+
$requirements = ModelRequirements::fromPromptData($capability, $this->messages, $this->modelConfig);
692704

693705
// If the model has been set, check if it meets the requirements
694706
if ($this->model !== null) {
@@ -1192,7 +1204,7 @@ private function getConfiguredModel(CapabilityEnum $capability): ModelInterface
11921204
*
11931205
* Request options are only applicable to API-based models that make HTTP requests.
11941206
*
1195-
* @since n.e.x.t
1207+
* @since 0.3.0
11961208
*
11971209
* @param ModelInterface $model The model to bind request options to.
11981210
* @return void

src/Providers/ApiBasedImplementation/AbstractApiBasedModel.php

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -108,7 +108,7 @@ final public function getConfig(): ModelConfig
108108
/**
109109
* {@inheritDoc}
110110
*
111-
* @since n.e.x.t
111+
* @since 0.3.0
112112
*/
113113
final public function setRequestOptions(RequestOptions $requestOptions): void
114114
{
@@ -118,7 +118,7 @@ final public function setRequestOptions(RequestOptions $requestOptions): void
118118
/**
119119
* {@inheritDoc}
120120
*
121-
* @since n.e.x.t
121+
* @since 0.3.0
122122
*/
123123
final public function getRequestOptions(): ?RequestOptions
124124
{

src/Providers/ApiBasedImplementation/Contracts/ApiBasedModelInterface.php

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -13,14 +13,14 @@
1313
* This interface extends ModelInterface to add request options support
1414
* for models that communicate with external APIs via HTTP.
1515
*
16-
* @since n.e.x.t
16+
* @since 0.3.0
1717
*/
1818
interface ApiBasedModelInterface extends ModelInterface
1919
{
2020
/**
2121
* Sets the request options for HTTP transport.
2222
*
23-
* @since n.e.x.t
23+
* @since 0.3.0
2424
*
2525
* @param RequestOptions $requestOptions The request options to use.
2626
* @return void
@@ -30,7 +30,7 @@ public function setRequestOptions(RequestOptions $requestOptions): void;
3030
/**
3131
* Gets the request options for HTTP transport.
3232
*
33-
* @since n.e.x.t
33+
* @since 0.3.0
3434
*
3535
* @return RequestOptions|null The request options, or null if not set.
3636
*/

tests/unit/Builders/PromptBuilderTest.php

Lines changed: 119 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3390,4 +3390,123 @@ public function testMethodChainingWithNewMethods(): void
33903390
$this->assertTrue($config->getLogprobs());
33913391
$this->assertEquals(3, $config->getTopLogprobs());
33923392
}
3393+
3394+
/**
3395+
* Tests isSupported method with explicit capability.
3396+
*
3397+
* @return void
3398+
*/
3399+
public function testIsSupportedWithExplicitCapability(): void
3400+
{
3401+
$builder = new PromptBuilder($this->registry, 'Test prompt');
3402+
3403+
// Mock registry to return a model supporting text generation
3404+
$this->registry->method('findModelsMetadataForSupport')
3405+
->willReturn([$this->createMock(ProviderModelsMetadata::class)]);
3406+
3407+
$this->assertTrue($builder->isSupported(CapabilityEnum::textGeneration()));
3408+
}
3409+
3410+
/**
3411+
* Tests isSupported method with inferred capability from output modalities.
3412+
*
3413+
* @return void
3414+
*/
3415+
public function testIsSupportedWithInferredCapability(): void
3416+
{
3417+
$builder = new PromptBuilder($this->registry, 'Test prompt');
3418+
$builder->asOutputModalities(ModalityEnum::image());
3419+
3420+
// Mock registry to return a model supporting image generation
3421+
$this->registry->method('findModelsMetadataForSupport')
3422+
->willReturn([$this->createMock(ProviderModelsMetadata::class)]);
3423+
3424+
// Should infer image generation capability
3425+
$this->assertTrue($builder->isSupported());
3426+
}
3427+
3428+
/**
3429+
* Tests isSupported method with inferred capability from model interfaces.
3430+
*
3431+
* @return void
3432+
*/
3433+
public function testIsSupportedWithInferredCapabilityFromModel(): void
3434+
{
3435+
$metadata = $this->createMock(ModelMetadata::class);
3436+
$metadata->method('getId')->willReturn('test-model');
3437+
$metadata->method('getSupportedCapabilities')->willReturn([
3438+
CapabilityEnum::textGeneration()
3439+
]);
3440+
$metadata->method('getSupportedOptions')->willReturn([
3441+
new SupportedOption(OptionEnum::inputModalities(), [
3442+
[ModalityEnum::text()]
3443+
])
3444+
]);
3445+
3446+
$result = new GenerativeAiResult('test-id', [
3447+
new Candidate(
3448+
new ModelMessage([new MessagePart('Test')]),
3449+
FinishReasonEnum::stop()
3450+
)
3451+
], new TokenUsage(10, 5, 15), $this->createTestProviderMetadata(), $this->createTestTextModelMetadata());
3452+
3453+
$model = $this->createMockTextGenerationModel($result, $metadata);
3454+
3455+
$builder = new PromptBuilder($this->registry, 'Test prompt');
3456+
$builder->usingModel($model);
3457+
3458+
// Should infer text generation capability from the model interface
3459+
$this->assertTrue($builder->isSupported());
3460+
}
3461+
3462+
/**
3463+
* Tests isSupported method when a model is explicitly set.
3464+
*
3465+
* @return void
3466+
*/
3467+
public function testIsSupportedWithModelSet(): void
3468+
{
3469+
$metadata = $this->createMock(ModelMetadata::class);
3470+
$metadata->method('getId')->willReturn('text-model');
3471+
$metadata->method('getSupportedCapabilities')->willReturn([
3472+
CapabilityEnum::textGeneration()
3473+
]);
3474+
// Mock getSupportedOptions to return required options
3475+
$metadata->method('getSupportedOptions')->willReturn([
3476+
new SupportedOption(OptionEnum::inputModalities(), [
3477+
[ModalityEnum::text()]
3478+
])
3479+
]);
3480+
3481+
$result = new GenerativeAiResult('test-id', [
3482+
new Candidate(
3483+
new ModelMessage([new MessagePart('Test')]),
3484+
FinishReasonEnum::stop()
3485+
)
3486+
], new TokenUsage(10, 5, 15), $this->createTestProviderMetadata(), $this->createTestTextModelMetadata());
3487+
3488+
$model = $this->createMockTextGenerationModel($result, $metadata);
3489+
3490+
$builder = new PromptBuilder($this->registry, 'Test prompt');
3491+
$builder->usingModel($model);
3492+
3493+
$this->assertTrue($builder->isSupported(CapabilityEnum::textGeneration()));
3494+
$this->assertFalse($builder->isSupported(CapabilityEnum::imageGeneration()));
3495+
}
3496+
3497+
/**
3498+
* Tests isSupported method when no models support the requirements.
3499+
*
3500+
* @return void
3501+
*/
3502+
public function testIsSupportedWithNoSupport(): void
3503+
{
3504+
$builder = new PromptBuilder($this->registry, 'Test prompt');
3505+
3506+
// Mock registry to return no models
3507+
$this->registry->method('findModelsMetadataForSupport')
3508+
->willReturn([]);
3509+
3510+
$this->assertFalse($builder->isSupported(CapabilityEnum::textGeneration()));
3511+
}
33933512
}

0 commit comments

Comments
 (0)