Skip to content

Commit 3d7990a

Browse files
committed
Add fluent API code examples to architecture documentation
This proposed set of changes to #2 and is doing a few things: 1. Adding Fluent API code examples (similar to those suggested by @JasonTheAdams [here](#2 (comment))) alongside the Traditional API examples. 2. Proposing a handful of helper methods to simplify the usage of Candidate Count and avoid implementers from needing to understand what _Candidate Count_ means. 3. Representing @JasonTheAdams' suggestion of `AiClient::withImage(string $mimeType, string $base64Blob)` to mimic the input simplicity that the Traditional API supports. 4. Adding the `AiClient::asJsonResponse()` and `AiClient::asArrayResponse()` as a helper methods for `usingOutputMime('application/json')` 5. Adding helper methods for specifying models that support a certain capability or option.
1 parent 6142c53 commit 3d7990a

File tree

1 file changed

+159
-4
lines changed

1 file changed

+159
-4
lines changed

docs/ARCHITECTURE.md

Lines changed: 159 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,13 @@ The following examples indicate how this SDK could eventually be used.
1919

2020
#### Generate text using any suitable model from any provider (most basic example)
2121

22+
##### Fluent API
23+
```php
24+
$text = AiClient::prompt('Write a 2-verse poem about PHP.')
25+
->generateText();
26+
```
27+
28+
##### Traditional API
2229
```php
2330
$text = AiClient::generateTextResult(
2431
'Write a 2-verse poem about PHP.'
@@ -27,6 +34,14 @@ $text = AiClient::generateTextResult(
2734

2835
#### Generate text using a Google model
2936

37+
##### Fluent API
38+
```php
39+
$text = AiClient::prompt('Write a 2-verse poem about PHP.')
40+
->usingModel('gemini-2.5-flash')
41+
->generateText();
42+
```
43+
44+
##### Traditional API
3045
```php
3146
$text = AiClient::generateTextResult(
3247
'Write a 2-verse poem about PHP.',
@@ -36,6 +51,14 @@ $text = AiClient::generateTextResult(
3651

3752
#### Generate multiple text candidates using an Anthropic model
3853

54+
##### Fluent API
55+
```php
56+
$texts = AiClient::prompt('Write a 2-verse poem about PHP.')
57+
->usingModel('claude-3.7-sonnet')
58+
->generateTexts(4);
59+
```
60+
61+
##### Traditional API
3962
```php
4063
$texts = AiClient::generateTextResult(
4164
'Write a 2-verse poem about PHP.',
@@ -48,6 +71,15 @@ $texts = AiClient::generateTextResult(
4871

4972
#### Generate an image using any suitable OpenAI model
5073

74+
##### Fluent API
75+
```php
76+
$imageFile = AiClient::prompt('Generate an illustration of the PHP elephant in the Carribean sea.')
77+
->usingProvider('openai')
78+
->usingModelSupportingImages() // Optional.
79+
->generateImage();
80+
```
81+
82+
##### Traditional API
5183
```php
5284
$modelsMetadata = AiClient::defaultRegistry()->findProviderModelsMetadataForSupport(
5385
'openai',
@@ -64,6 +96,14 @@ $imageFile = AiClient::generateImageResult(
6496

6597
#### Generate an image using any suitable model from any provider
6698

99+
##### Fluent API
100+
```php
101+
$imageFile = AiClient::prompt('Generate an illustration of the PHP elephant in the Carribean sea.')
102+
->usingModelSupportingImages() // Optional.
103+
->generateImage();
104+
```
105+
106+
##### Traditional API
67107
```php
68108
$providerModelsMetadata = AiClient::defaultRegistry()->findModelsMetadataForSupport(
69109
new AiModelRequirements([AiCapability::IMAGE_GENERATION])
@@ -81,6 +121,14 @@ $imageFile = AiClient::generateImageResult(
81121

82122
_Note: This does effectively the exact same as [the first code example](#generate-text-using-any-suitable-model-from-any-provider-most-basic-example), but more verbosely. In other words, if you omit the model parameter, the SDK will do this internally._
83123

124+
##### Fluent API
125+
```php
126+
$text = AiClient::prompt('Write a 2-verse poem about PHP.')
127+
->usingModelSupportingText() // Optional.
128+
->generateText();
129+
```
130+
131+
##### Traditional API
84132
```php
85133
$providerModelsMetadata = AiClient::defaultRegistry()->findModelsMetadataForSupport(
86134
new AiModelRequirements([AiCapability::TEXT_GENERATION])
@@ -98,6 +146,14 @@ $text = AiClient::generateTextResult(
98146

99147
_Note: Since this omits the model parameter, the SDK will automatically determine which models are suitable and use any of them, similar to [the first code example](#generate-text-using-any-suitable-model-from-any-provider-most-basic-example). Since it knows the input includes an image, it can internally infer that the model needs to not only support `AiCapability::TEXT_GENERATION`, but also `AiOption::INPUT_MODALITIES => ['text', 'image']`._
100148

149+
##### Fluent API
150+
```php
151+
$text = AiClient::prompt('Generate alternative text for this image.')
152+
->withImage('image/png', $base64blob)
153+
->generateText();
154+
```
155+
156+
##### Traditional API
101157
```php
102158
$text = AiClient::generateTextResult(
103159
[
@@ -116,6 +172,17 @@ $text = AiClient::generateTextResult(
116172

117173
_Note: Similarly to the previous example, even without specifying the model here, the SDK will be able to infer required model capabilities because it can detect that multiple chat messages are passed. Therefore it will internally only consider models that support `AiCapability::TEXT_GENERATION` as well as `AiCapability::CHAT_HISTORY`._
118174

175+
##### Fluent API
176+
```php
177+
$text = AiClient::prompt('Can you repeat that please?')
178+
->withHistory(
179+
new UserMessage('Do you spell it WordPress or Wordpress?'),
180+
new AgentMessage('The correct spelling is WordPress.')
181+
)
182+
->generateText();
183+
```
184+
185+
##### Traditional API
119186
```php
120187
$text = AiClient::generateTextResult(
121188
[
@@ -139,6 +206,21 @@ $text = AiClient::generateTextResult(
139206

140207
_Note: Unlike the previous two examples, to require JSON output it is necessary to go the verbose route, since it is impossible for the SDK to detect whether you require JSON output purely from the prompt input. Therefore this code example contains the logic to manually search for suitable models and then use one of them for the task._
141208

209+
##### Fluent API
210+
```php
211+
// Verbose.
212+
$text = AiClient::prompt('Transform the following CSV content into a JSON array of row data.')
213+
->asJsonResponse()
214+
->usingOutputSchema(['name' => 'string', 'age' => 'integer'])
215+
->generateText();
216+
217+
// Simple.
218+
$text = AiClient::prompt('Transform the following CSV content into a JSON array of row data.')
219+
->asJsonResponse(['name' => 'string', 'age' => 'integer'])
220+
->generateText();
221+
```
222+
223+
##### Traditional API
142224
```php
143225
$providerModelsMetadata = AiClient::defaultRegistry()->findModelsMetadataForSupport(
144226
new AiModelRequirements(
@@ -178,6 +260,13 @@ $jsonString = AiClient::generateTextResult(
178260

179261
#### Generate embeddings using any suitable model from any provider
180262

263+
##### Fluent API
264+
```php
265+
$embeddings = AiClient::prompt('A very long text.', 'Another very long text.', 'More long text.')
266+
->generateEmbeddings();
267+
```
268+
269+
##### Traditional API
181270
```php
182271
$providerModelsMetadata = AiClient::defaultRegistry()->findModelsMetadataForSupport(
183272
new AiModelRequirements([AiCapability::EMBEDDING_GENERATION])
@@ -217,19 +306,34 @@ classDiagram
217306
direction LR
218307
namespace Ai {
219308
class AiClient {
220-
+prompt(?string $text) PromptBuilder$
221-
+message(?string $text) MessageBuilder$
309+
+prompt(...string $text) PromptBuilder$
310+
+message(...string $text) MessageBuilder$
222311
}
223312
224313
class PromptBuilder {
225314
+withText(string $text) self
315+
+withImage(string $mimeType, string $base64Blob) self
226316
+withImageFile(File $file) self
227317
+withAudioFile(File $file) self
228318
+withVideoFile(File $file) self
229319
+withFunctionResponse(FunctionResponse $functionResponse) self
230320
+withMessageParts(...MessagePart $part) self
231321
+withHistory(...Message $messages) self
232322
+usingModel(AiModel $model) self
323+
+usingModelSupporting(...AiCapability|AiOption $aiCapabilityOrOption) self
324+
+usingModelSupportingCapability(...AiCapability $aiCapability) self
325+
+usingModelSupportingOption(...AiOption $aiOption) self
326+
+usingModelSupportingAudio() self
327+
+usingModelSupportingHistory() self
328+
+usingModelSupportingEmbeddings() self
329+
+usingModelSupportingImages() self
330+
+usingModelSupportingJsonOutput() self
331+
+usingModelSupportingMusic() self
332+
+usingModelSupportingOutputSchema() self
333+
+usingModelSupportingSpeech() self
334+
+usingModelSupportingText() self
335+
+usingModelSupportingTextToSpeech() self
336+
+usingModelSupportingVideo() self
233337
+usingSystemInstruction(string|MessagePart[]|Message $systemInstruction) self
234338
+usingMaxTokens(int $maxTokens) self
235339
+usingTemperature(float $temperature) self
@@ -240,24 +344,41 @@ direction LR
240344
+usingOutputMime(string $mimeType) self
241345
+usingOutputSchema(array< string, mixed > $schema) self
242346
+usingOutputModalities(...AiModality $modalities) self
347+
+asArrayResponse(?array< string, mixed > $schema) self
348+
+asJsonResponse(?array< string, mixed > $schema) self
243349
+generateResult() GenerativeAiResult
350+
+generateResults(int $candidateCount) GenerativeAiResult[]
244351
+generateOperation() GenerativeAiOperation
352+
+generateOperations(int $candidateCount) GenerativeAiOperation[]
245353
+generateTextResult() GenerativeAiResult
354+
+generateTextResults(int $candidateCount) GenerativeAiResult[]
246355
+streamGenerateTextResult() Generator< GenerativeAiResult >
247356
+generateImageResult() GenerativeAiResult
357+
+generateImageResults(int $candidateCount) GenerativeAiResult[]
248358
+convertTextToSpeechResult() GenerativeAiResult
359+
+convertTextToSpeechResults(int $candidateCount) GenerativeAiResult[]
249360
+generateSpeechResult() GenerativeAiResult
361+
+generateSpeechResults(int $candidateCount) GenerativeAiResult[]
250362
+generateEmbeddingsResult() EmbeddingResult
363+
+generateEmbeddingsResults(int $candidateCount) EmbeddingResult[]
251364
+generateTextOperation() GenerativeAiOperation
365+
+generateTextOperations(int $candidateCount) GenerativeAiOperation[]
252366
+generateImageOperation() GenerativeAiOperation
367+
+generateImageOperations(int $candidateCount) GenerativeAiOperation[]
253368
+convertTextToSpeechOperation() GenerativeAiOperation
254369
+generateSpeechOperation() GenerativeAiOperation
370+
+generateSpeechOperations(int $candidateCount) GenerativeAiOperation[]
255371
+generateEmbeddingsOperation() EmbeddingOperation
372+
+generateEmbeddingsOperations(int $candidateCount) EmbeddingOperation[]
256373
+generateText() string
374+
+generateTexts(int $candidateCount) string[]
257375
+streamGenerateText() Generator< string >
258376
+generateImage() File
377+
+generateImages(int $candidateCount) File[]
259378
+convertTextToSpeech() File
379+
+convertTextToSpeeches(int $candidateCount) File[]
260380
+generateSpeech() File
381+
+generateSpeeches(int $candidateCount) File[]
261382
+generateEmbeddings() Embedding[]
262383
+getModelRequirements() AiModelRequirements
263384
+isSupported() bool
@@ -266,6 +387,7 @@ direction LR
266387
class MessageBuilder {
267388
+usingRole(MessageRole $role) self
268389
+withText(string $text) self
390+
+withImage(string $mimeType, string $base64Blob) self
269391
+withImageFile(File $file) self
270392
+withAudioFile(File $file) self
271393
+withVideoFile(File $file) self
@@ -356,8 +478,8 @@ classDiagram
356478
direction LR
357479
namespace Ai {
358480
class AiClient {
359-
+prompt(?string $text) PromptBuilder$
360-
+message(?string $text) MessageBuilder$
481+
+prompt(...string $text) PromptBuilder$
482+
+message(...string $text) MessageBuilder$
361483
+defaultRegistry() AiProviderRegistry$
362484
+isConfigured(AiProviderAvailability $availability) bool$
363485
+generateResult(string|MessagePart|MessagePart[]|Message|Message[] $prompt, AiModel $model) GenerativeAiResult$
@@ -377,13 +499,28 @@ direction LR
377499
378500
class PromptBuilder {
379501
+withText(string $text) self
502+
+withImage(string $mimeType, string $base64Blob) self
380503
+withImageFile(File $file) self
381504
+withAudioFile(File $file) self
382505
+withVideoFile(File $file) self
383506
+withFunctionResponse(FunctionResponse $functionResponse) self
384507
+withMessageParts(...MessagePart $part) self
385508
+withHistory(...Message $messages) self
386509
+usingModel(AiModel $model) self
510+
+usingModelSupporting(...AiCapability|AiOption $aiCapabilityOrOption) self
511+
+usingModelSupportingCapability(...AiCapability $aiCapability) self
512+
+usingModelSupportingOption(...AiOption $aiOption) self
513+
+usingModelSupportingAudio() self
514+
+usingModelSupportingHistory() self
515+
+usingModelSupportingEmbeddings() self
516+
+usingModelSupportingImages() self
517+
+usingModelSupportingJsonOutput() self
518+
+usingModelSupportingMusic() self
519+
+usingModelSupportingOutputSchema() self
520+
+usingModelSupportingSpeech() self
521+
+usingModelSupportingText() self
522+
+usingModelSupportingTextToSpeech() self
523+
+usingModelSupportingVideo() self
387524
+usingSystemInstruction(string|MessagePart[]|Message $systemInstruction) self
388525
+usingMaxTokens(int $maxTokens) self
389526
+usingTemperature(float $temperature) self
@@ -394,24 +531,41 @@ direction LR
394531
+usingOutputMime(string $mimeType) self
395532
+usingOutputSchema(array< string, mixed > $schema) self
396533
+usingOutputModalities(...AiModality $modalities) self
534+
+asArrayResponse(?array< string, mixed > $schema) self
535+
+asJsonResponse(?array< string, mixed > $schema) self
397536
+generateResult() GenerativeAiResult
537+
+generateResults(int $candidateCount) GenerativeAiResult[]
398538
+generateOperation() GenerativeAiOperation
539+
+generateOperations(int $candidateCount) GenerativeAiOperation[]
399540
+generateTextResult() GenerativeAiResult
541+
+generateTextResults(int $candidateCount) GenerativeAiResult[]
400542
+streamGenerateTextResult() Generator< GenerativeAiResult >
401543
+generateImageResult() GenerativeAiResult
544+
+generateImageResults(int $candidateCount) GenerativeAiResult[]
402545
+convertTextToSpeechResult() GenerativeAiResult
546+
+convertTextToSpeechResults(int $candidateCount) GenerativeAiResult[]
403547
+generateSpeechResult() GenerativeAiResult
548+
+generateSpeechResults(int $candidateCount) GenerativeAiResult[]
404549
+generateEmbeddingsResult() EmbeddingResult
550+
+generateEmbeddingsResults(int $candidateCount) EmbeddingResult[]
405551
+generateTextOperation() GenerativeAiOperation
552+
+generateTextOperations(int $candidateCount) GenerativeAiOperation[]
406553
+generateImageOperation() GenerativeAiOperation
554+
+generateImageOperations(int $candidateCount) GenerativeAiOperation[]
407555
+convertTextToSpeechOperation() GenerativeAiOperation
408556
+generateSpeechOperation() GenerativeAiOperation
557+
+generateSpeechOperations(int $candidateCount) GenerativeAiOperation[]
409558
+generateEmbeddingsOperation() EmbeddingOperation
559+
+generateEmbeddingsOperations(int $candidateCount) EmbeddingOperation[]
410560
+generateText() string
561+
+generateTexts(int $candidateCount) string[]
411562
+streamGenerateText() Generator< string >
412563
+generateImage() File
564+
+generateImages(int $candidateCount) File[]
413565
+convertTextToSpeech() File
566+
+convertTextToSpeeches(int $candidateCount) File[]
414567
+generateSpeech() File
568+
+generateSpeeches(int $candidateCount) File[]
415569
+generateEmbeddings() Embedding[]
416570
+getModelRequirements() AiModelRequirements
417571
+isSupported() bool
@@ -420,6 +574,7 @@ direction LR
420574
class MessageBuilder {
421575
+usingRole(MessageRole $role) self
422576
+withText(string $text) self
577+
+withImage(string $mimeType, string $base64Blob) self
423578
+withImageFile(File $file) self
424579
+withAudioFile(File $file) self
425580
+withVideoFile(File $file) self

0 commit comments

Comments
 (0)