@@ -32,168 +32,177 @@ Feature: Generate AI content
3232 use WordPress\AiClient\Results\Enums\FinishReasonEnum;
3333
3434 if ( ! interface_exists( 'WordPress\AiClient\Providers\Models\Contracts\ModelInterface' ) ) {
35- return;
35+ return;
3636 }
3737
3838 class WP_CLI_Mock_Model implements ModelInterface, TextGenerationModelInterface, ImageGenerationModelInterface {
39- private $id;
40- private $config;
41-
42- public function __construct( $id ) {
43- $this->id = $id;
44- $this->config = new ModelConfig();
45- }
46-
47- public function metadata(): ModelMetadata {
48- return new ModelMetadata(
49- $this->id,
50- 'WP-CLI Mock Model',
51- // Supported capabilities.
52- [
53- CapabilityEnum::textGeneration(),
54- CapabilityEnum::imageGeneration(),
55- ],
56- // Supported options.
57- [
58- new SupportedOption(OptionEnum::candidateCount()),
59- new SupportedOption(OptionEnum::outputMimeType(), ['image/png']),
60- new SupportedOption(OptionEnum::outputFileType(), [FileTypeEnum::inline()]),
61- new SupportedOption(OptionEnum::inputModalities(), [
62- [ModalityEnum::text()],
63- [ModalityEnum::image()],
64- [ModalityEnum::text(), ModalityEnum::image()],
65- ]),
66- new SupportedOption(
67- OptionEnum::outputModalities(),
68- [
69- [ModalityEnum::text()],
70- [ModalityEnum::image()],
71- [ModalityEnum::text(), ModalityEnum::image()],
72- ]
73- ),
74- new SupportedOption(OptionEnum::candidateCount()),
75- new SupportedOption(OptionEnum::outputMimeType(), ['image/png']),
76- new SupportedOption(OptionEnum::outputFileType(), [FileTypeEnum::inline(), FileTypeEnum::remote()]),
77- new SupportedOption(OptionEnum::outputMediaOrientation(), [
78- MediaOrientationEnum::square(),
79- MediaOrientationEnum::landscape(),
80- MediaOrientationEnum::portrait(),
81- ]),
82- new SupportedOption(OptionEnum::outputMediaAspectRatio(), ['1:1', '7:4', '4:7']),
83- new SupportedOption(OptionEnum::customOptions()),
84- ]
85- );
86- }
87-
88- public function providerMetadata(): ProviderMetadata {
89- return WP_CLI_Mock_Provider::metadata();
90- }
91-
92- public function setConfig( ModelConfig $config ): void {
93- $this->config = $config;
94- }
95-
96- public function getConfig(): ModelConfig {
97- return $this->config;
98- }
99-
100- public function generateTextResult(array $prompt): GenerativeAiResult {
101- // throw new RuntimeException('No candidates were generated');
102-
103- $modelMessage = new ModelMessage([
104- new MessagePart('This is mock-generated text')
105- ]);
106- $candidate = new Candidate(
107- $modelMessage,
108- FinishReasonEnum::stop(),
109- 42
110- );
111- $tokenUsage = new TokenUsage( 10, 42, 52 );
112- return new GenerativeAiResult(
113- 'result_123',
114- [ $candidate ],
115- $tokenUsage,
116- $this->providerMetadata(),
117- $this->metadata(),
118- [ 'provider' => 'wp-cli-mock-provider' ]
119- );
120- }
121-
122- public function streamGenerateTextResult(array $prompt): Generator {
123- yield from [];
124- }
125-
126- public function generateImageResult(array $prompt): GenerativeAiResult {
127- // throw new RuntimeException('No candidates were generated');
128-
129- $modelMessage = new ModelMessage( [
130- new MessagePart(
131- // A base64-encoded 1x1 black PNG.
132- new File(
133- 'iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAQAAAC1HAwCAAAAC0lEQVR42mNkYAAAAAYAAjCB0C8AAAAASUVORK5CYII=',
134- 'image/png'
135- )
136- )
137- ] );
138- $candidate = new Candidate(
139- $modelMessage,
140- FinishReasonEnum::stop(),
141- 42
142- );
143- $tokenUsage = new TokenUsage(10, 42, 52);
144- return new GenerativeAiResult(
145- 'result_123',
146- [ $candidate ],
147- $tokenUsage,
148- $this->providerMetadata(),
149- $this->metadata(),
150- [ 'provider' => 'wp-cli-mock-provider' ]
151- );
152- }
153-
39+ private $id;
40+ private $config;
41+
42+ public function __construct( $id ) {
43+ $this->id = $id;
44+ $this->config = new ModelConfig();
45+ }
46+
47+ public function metadata(): ModelMetadata {
48+ return new ModelMetadata(
49+ $this->id,
50+ 'WP-CLI Mock Model',
51+ // Supported capabilities.
52+ [
53+ CapabilityEnum::textGeneration(),
54+ CapabilityEnum::imageGeneration(),
55+ ],
56+ // Supported options.
57+ [
58+ new SupportedOption( OptionEnum::candidateCount() ),
59+ new SupportedOption( OptionEnum::outputMimeType(), [ 'image/png' ] ),
60+ new SupportedOption( OptionEnum::outputFileType(), [ FileTypeEnum::inline() ] ),
61+ new SupportedOption(
62+ OptionEnum::inputModalities(),
63+ [
64+ [ ModalityEnum::text() ],
65+ [ ModalityEnum::image() ],
66+ [ ModalityEnum::text(), ModalityEnum::image() ],
67+ ]
68+ ),
69+ new SupportedOption(
70+ OptionEnum::outputModalities(),
71+ [
72+ [ ModalityEnum::text() ],
73+ [ ModalityEnum::image() ],
74+ [ ModalityEnum::text(), ModalityEnum::image() ],
75+ ]
76+ ),
77+ new SupportedOption( OptionEnum::candidateCount() ),
78+ new SupportedOption( OptionEnum::outputMimeType(), [ 'image/png' ] ),
79+ new SupportedOption( OptionEnum::outputFileType(), [ FileTypeEnum::inline(), FileTypeEnum::remote() ] ),
80+ new SupportedOption(
81+ OptionEnum::outputMediaOrientation(),
82+ [
83+ MediaOrientationEnum::square(),
84+ MediaOrientationEnum::landscape(),
85+ MediaOrientationEnum::portrait(),
86+ ]
87+ ),
88+ new SupportedOption( OptionEnum::outputMediaAspectRatio(), [ '1:1', '7:4', '4:7' ] ),
89+ new SupportedOption( OptionEnum::customOptions() ),
90+ ]
91+ );
92+ }
93+
94+ public function providerMetadata(): ProviderMetadata {
95+ return WP_CLI_Mock_Provider::metadata();
96+ }
97+
98+ public function setConfig( ModelConfig $config ): void {
99+ $this->config = $config;
100+ }
101+
102+ public function getConfig(): ModelConfig {
103+ return $this->config;
104+ }
105+
106+ public function generateTextResult( array $prompt ): GenerativeAiResult {
107+ // throw new RuntimeException('No candidates were generated');
108+
109+ $modelMessage = new ModelMessage(
110+ [
111+ new MessagePart( 'This is mock-generated text' ),
112+ ]
113+ );
114+ $candidate = new Candidate(
115+ $modelMessage,
116+ FinishReasonEnum::stop(),
117+ 42
118+ );
119+ $tokenUsage = new TokenUsage( 10, 42, 52 );
120+ return new GenerativeAiResult(
121+ 'result_123',
122+ [ $candidate ],
123+ $tokenUsage,
124+ $this->providerMetadata(),
125+ $this->metadata(),
126+ [ 'provider' => 'wp-cli-mock-provider' ]
127+ );
128+ }
129+
130+ public function streamGenerateTextResult( array $prompt ): Generator {
131+ yield from [];
132+ }
133+
134+ public function generateImageResult( array $prompt ): GenerativeAiResult {
135+ // throw new RuntimeException('No candidates were generated');
136+
137+ $modelMessage = new ModelMessage(
138+ [
139+ new MessagePart(
140+ // A base64-encoded 1x1 black PNG.
141+ new File(
142+ 'iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAQAAAC1HAwCAAAAC0lEQVR42mNkYAAAAAYAAjCB0C8AAAAASUVORK5CYII=',
143+ 'image/png'
144+ )
145+ ),
146+ ]
147+ );
148+ $candidate = new Candidate(
149+ $modelMessage,
150+ FinishReasonEnum::stop(),
151+ 42
152+ );
153+ $tokenUsage = new TokenUsage( 10, 42, 52 );
154+ return new GenerativeAiResult(
155+ 'result_123',
156+ [ $candidate ],
157+ $tokenUsage,
158+ $this->providerMetadata(),
159+ $this->metadata(),
160+ [ 'provider' => 'wp-cli-mock-provider' ]
161+ );
162+ }
154163 }
155164
156165 class WP_CLI_Mock_Provider implements ProviderInterface {
157- public static function metadata(): ProviderMetadata {
158- return new ProviderMetadata( 'wp-cli-mock-provider', 'WP-CLI Mock Provider', ProviderTypeEnum::cloud() );
159- }
160-
161- public static function model( string $modelId, ?ModelConfig $modelConfig = null ): ModelInterface {
162- return new WP_CLI_Mock_Model( $modelId );
163- }
164-
165- public static function availability(): ProviderAvailabilityInterface {
166- return new class() implements ProviderAvailabilityInterface {
167- public function isConfigured(): bool {
168- return true;
169- }
170- };
171- }
172-
173- public static function modelMetadataDirectory(): ModelMetadataDirectoryInterface {
174- return new class() implements ModelMetadataDirectoryInterface {
175- public function listModelMetadata(): array {
176- return [
177- ( new WP_CLI_Mock_Model( 'wp-cli-mock-model' ) )->metadata()
178- ];
179- }
180-
181- public function hasModelMetadata( string $modelId ): bool {
182- return true;
183- }
184-
185- public function getModelMetadata( string $modelId ): ModelMetadata {
186- return self ::model()->metadata();
187- }
188- };
189- }
166+ public static function metadata(): ProviderMetadata {
167+ return new ProviderMetadata( 'wp-cli-mock-provider', 'WP-CLI Mock Provider', ProviderTypeEnum::cloud() );
168+ }
169+
170+ public static function model( string $modelId, ?ModelConfig $modelConfig = null ): ModelInterface {
171+ return new WP_CLI_Mock_Model( $modelId );
172+ }
173+
174+ public static function availability(): ProviderAvailabilityInterface {
175+ return new class() implements ProviderAvailabilityInterface {
176+ public function isConfigured(): bool {
177+ return true;
178+ }
179+ };
180+ }
181+
182+ public static function modelMetadataDirectory(): ModelMetadataDirectoryInterface {
183+ return new class() implements ModelMetadataDirectoryInterface {
184+ public function listModelMetadata(): array {
185+ return [
186+ ( new WP_CLI_Mock_Model( 'wp-cli-mock-model' ) )->metadata(),
187+ ];
188+ }
189+
190+ public function hasModelMetadata( string $modelId ): bool {
191+ return true;
192+ }
193+
194+ public function getModelMetadata( string $modelId ): ModelMetadata {
195+ return WP_CLI_Mock_Provider ::model( $modelId )->metadata();
196+ }
197+ };
198+ }
190199 }
191200
192201 WP_CLI::add_wp_hook(
193- 'init',
194- static function () {
195- AiClient::defaultRegistry()->registerProvider( WP_CLI_Mock_Provider::class );
196- }
202+ 'init',
203+ static function () {
204+ AiClient::defaultRegistry()->registerProvider( WP_CLI_Mock_Provider::class );
205+ }
197206 );
198207 """
199208
0 commit comments