Skip to content

Commit 02d3433

Browse files
committed
feat: adds output schema and mime type support
1 parent 8f6ff62 commit 02d3433

File tree

2 files changed

+150
-1
lines changed

2 files changed

+150
-1
lines changed

src/Providers/Models/DTO/ModelConfig.php

Lines changed: 95 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,8 @@
3333
* logprobs?: bool,
3434
* topLogprobs?: int,
3535
* tools?: array<int, ToolArrayShape>,
36+
* outputMimeType?: string,
37+
* outputSchema?: array<string, mixed>,
3638
* customOptions?: array<string, mixed>
3739
* }
3840
*
@@ -53,6 +55,8 @@ class ModelConfig extends AbstractDataValueObject
5355
public const KEY_LOGPROBS = 'logprobs';
5456
public const KEY_TOP_LOGPROBS = 'topLogprobs';
5557
public const KEY_TOOLS = 'tools';
58+
public const KEY_OUTPUT_MIME_TYPE = 'outputMimeType';
59+
public const KEY_OUTPUT_SCHEMA = 'outputSchema';
5660
public const KEY_CUSTOM_OPTIONS = 'customOptions';
5761

5862
/**
@@ -120,6 +124,16 @@ class ModelConfig extends AbstractDataValueObject
120124
*/
121125
protected ?array $tools = null;
122126

127+
/**
128+
* @var string|null Output MIME type.
129+
*/
130+
protected ?string $outputMimeType = null;
131+
132+
/**
133+
* @var array<string, mixed>|null Output schema (JSON schema).
134+
*/
135+
protected ?array $outputSchema = null;
136+
123137
/**
124138
* @var array<string, mixed> Custom provider-specific options.
125139
*/
@@ -437,6 +451,62 @@ public function getTools(): ?array
437451
return $this->tools;
438452
}
439453

454+
/**
455+
* Sets the output MIME type.
456+
*
457+
* @since n.e.x.t
458+
*
459+
* @param string $outputMimeType The output MIME type.
460+
*/
461+
public function setOutputMimeType(string $outputMimeType): void
462+
{
463+
$this->outputMimeType = $outputMimeType;
464+
}
465+
466+
/**
467+
* Gets the output MIME type.
468+
*
469+
* @since n.e.x.t
470+
*
471+
* @return string|null The output MIME type.
472+
*/
473+
public function getOutputMimeType(): ?string
474+
{
475+
return $this->outputMimeType;
476+
}
477+
478+
/**
479+
* Sets the output schema.
480+
*
481+
* When setting an output schema, this method automatically sets
482+
* the output MIME type to "application/json" if not already set.
483+
*
484+
* @since n.e.x.t
485+
*
486+
* @param array<string, mixed> $outputSchema The output schema (JSON schema).
487+
*/
488+
public function setOutputSchema(array $outputSchema): void
489+
{
490+
$this->outputSchema = $outputSchema;
491+
492+
// Automatically set outputMimeType to application/json when schema is provided
493+
if ($this->outputMimeType === null) {
494+
$this->outputMimeType = 'application/json';
495+
}
496+
}
497+
498+
/**
499+
* Gets the output schema.
500+
*
501+
* @since n.e.x.t
502+
*
503+
* @return array<string, mixed>|null The output schema.
504+
*/
505+
public function getOutputSchema(): ?array
506+
{
507+
return $this->outputSchema;
508+
}
509+
440510
/**
441511
* Sets a single custom option.
442512
*
@@ -552,6 +622,15 @@ public static function getJsonSchema(): array
552622
'items' => Tool::getJsonSchema(),
553623
'description' => 'Tools available to the model.',
554624
],
625+
self::KEY_OUTPUT_MIME_TYPE => [
626+
'type' => 'string',
627+
'description' => 'Output MIME type.',
628+
],
629+
self::KEY_OUTPUT_SCHEMA => [
630+
'type' => 'object',
631+
'additionalProperties' => true,
632+
'description' => 'Output schema (JSON schema).',
633+
],
555634
self::KEY_CUSTOM_OPTIONS => [
556635
'type' => 'object',
557636
'additionalProperties' => true,
@@ -632,6 +711,14 @@ static function (ModalityEnum $modality): string {
632711
}, $this->tools));
633712
}
634713

714+
if ($this->outputMimeType !== null) {
715+
$data[self::KEY_OUTPUT_MIME_TYPE] = $this->outputMimeType;
716+
}
717+
718+
if ($this->outputSchema !== null) {
719+
$data[self::KEY_OUTPUT_SCHEMA] = $this->outputSchema;
720+
}
721+
635722
$data[self::KEY_CUSTOM_OPTIONS] = $this->customOptions;
636723

637724
return $data;
@@ -703,6 +790,14 @@ public static function fromArray(array $array): self
703790
}, $array[self::KEY_TOOLS]));
704791
}
705792

793+
if (isset($array[self::KEY_OUTPUT_MIME_TYPE])) {
794+
$config->setOutputMimeType($array[self::KEY_OUTPUT_MIME_TYPE]);
795+
}
796+
797+
if (isset($array[self::KEY_OUTPUT_SCHEMA])) {
798+
$config->setOutputSchema($array[self::KEY_OUTPUT_SCHEMA]);
799+
}
800+
706801
if (isset($array[self::KEY_CUSTOM_OPTIONS])) {
707802
$config->setCustomOptions($array[self::KEY_CUSTOM_OPTIONS]);
708803
}

tests/unit/Providers/Models/DTO/ModelConfigTest.php

Lines changed: 55 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -53,6 +53,8 @@ public function testDefaultConstructor(): void
5353
$this->assertNull($config->getLogprobs());
5454
$this->assertNull($config->getTopLogprobs());
5555
$this->assertNull($config->getTools());
56+
$this->assertNull($config->getOutputMimeType());
57+
$this->assertNull($config->getOutputSchema());
5658
$this->assertEquals([], $config->getCustomOptions());
5759
}
5860

@@ -122,6 +124,20 @@ public function testSettersAndGetters(): void
122124
$config->setTools($tools);
123125
$this->assertEquals($tools, $config->getTools());
124126

127+
// Test output MIME type
128+
$config->setOutputMimeType('application/json');
129+
$this->assertEquals('application/json', $config->getOutputMimeType());
130+
131+
// Test output schema
132+
$outputSchema = [
133+
'type' => 'object',
134+
'properties' => [
135+
'result' => ['type' => 'string']
136+
]
137+
];
138+
$config->setOutputSchema($outputSchema);
139+
$this->assertEquals($outputSchema, $config->getOutputSchema());
140+
125141
// Test custom options
126142
$customOptions = ['custom_param' => 'value', 'another_param' => 123];
127143
$config->setCustomOptions($customOptions);
@@ -146,7 +162,8 @@ public function testGetJsonSchema(): void
146162
$expectedProperties = [
147163
ModelConfig::KEY_OUTPUT_MODALITIES, ModelConfig::KEY_SYSTEM_INSTRUCTION, ModelConfig::KEY_CANDIDATE_COUNT, ModelConfig::KEY_MAX_TOKENS,
148164
ModelConfig::KEY_TEMPERATURE, ModelConfig::KEY_TOP_P, ModelConfig::KEY_TOP_K, ModelConfig::KEY_STOP_SEQUENCES, ModelConfig::KEY_PRESENCE_PENALTY,
149-
ModelConfig::KEY_FREQUENCY_PENALTY, ModelConfig::KEY_LOGPROBS, ModelConfig::KEY_TOP_LOGPROBS, ModelConfig::KEY_TOOLS, ModelConfig::KEY_CUSTOM_OPTIONS
165+
ModelConfig::KEY_FREQUENCY_PENALTY, ModelConfig::KEY_LOGPROBS, ModelConfig::KEY_TOP_LOGPROBS, ModelConfig::KEY_TOOLS,
166+
ModelConfig::KEY_OUTPUT_MIME_TYPE, ModelConfig::KEY_OUTPUT_SCHEMA, ModelConfig::KEY_CUSTOM_OPTIONS
150167
];
151168

152169
foreach ($expectedProperties as $property) {
@@ -159,6 +176,8 @@ public function testGetJsonSchema(): void
159176
$this->assertEquals('integer', $schema['properties'][ModelConfig::KEY_CANDIDATE_COUNT]['type']);
160177
$this->assertEquals('number', $schema['properties'][ModelConfig::KEY_TEMPERATURE]['type']);
161178
$this->assertEquals('boolean', $schema['properties'][ModelConfig::KEY_LOGPROBS]['type']);
179+
$this->assertEquals('string', $schema['properties'][ModelConfig::KEY_OUTPUT_MIME_TYPE]['type']);
180+
$this->assertEquals('object', $schema['properties'][ModelConfig::KEY_OUTPUT_SCHEMA]['type']);
162181
$this->assertEquals('object', $schema['properties'][ModelConfig::KEY_CUSTOM_OPTIONS]['type']);
163182

164183
// Check constraints
@@ -192,6 +211,8 @@ public function testToArrayAllProperties(): void
192211
$config->setLogprobs(true);
193212
$config->setTopLogprobs(10);
194213
$config->setTools([$tool]);
214+
$config->setOutputMimeType('application/json');
215+
$config->setOutputSchema(['type' => 'object']);
195216
$config->setCustomOptions(['key' => 'value']);
196217

197218
$array = $config->toArray();
@@ -210,6 +231,8 @@ public function testToArrayAllProperties(): void
210231
$this->assertTrue($array[ModelConfig::KEY_LOGPROBS]);
211232
$this->assertEquals(10, $array[ModelConfig::KEY_TOP_LOGPROBS]);
212233
$this->assertCount(1, $array[ModelConfig::KEY_TOOLS]);
234+
$this->assertEquals('application/json', $array[ModelConfig::KEY_OUTPUT_MIME_TYPE]);
235+
$this->assertEquals(['type' => 'object'], $array[ModelConfig::KEY_OUTPUT_SCHEMA]);
213236
$this->assertEquals(['key' => 'value'], $array[ModelConfig::KEY_CUSTOM_OPTIONS]);
214237
}
215238

@@ -283,6 +306,8 @@ public function testFromArrayAllProperties(): void
283306
]
284307
]
285308
],
309+
ModelConfig::KEY_OUTPUT_MIME_TYPE => 'application/json',
310+
ModelConfig::KEY_OUTPUT_SCHEMA => ['type' => 'array', 'items' => ['type' => 'string']],
286311
ModelConfig::KEY_CUSTOM_OPTIONS => ['custom' => true]
287312
];
288313

@@ -304,6 +329,8 @@ public function testFromArrayAllProperties(): void
304329
$this->assertFalse($config->getLogprobs());
305330
$this->assertEquals(3, $config->getTopLogprobs());
306331
$this->assertCount(1, $config->getTools());
332+
$this->assertEquals('application/json', $config->getOutputMimeType());
333+
$this->assertEquals(['type' => 'array', 'items' => ['type' => 'string']], $config->getOutputSchema());
307334
$this->assertEquals(['custom' => true], $config->getCustomOptions());
308335
}
309336

@@ -482,6 +509,33 @@ public function testImplementsCorrectInterfaces(): void
482509
);
483510
}
484511

512+
/**
513+
* Tests automatic output MIME type setting when schema is provided.
514+
*
515+
* @return void
516+
*/
517+
public function testOutputSchemaAutomaticallySetsJsonMimeType(): void
518+
{
519+
$config = new ModelConfig();
520+
521+
// Test that setting output schema automatically sets MIME type to application/json
522+
$this->assertNull($config->getOutputMimeType());
523+
524+
$schema = ['type' => 'object', 'properties' => ['test' => ['type' => 'string']]];
525+
$config->setOutputSchema($schema);
526+
527+
$this->assertEquals('application/json', $config->getOutputMimeType());
528+
$this->assertEquals($schema, $config->getOutputSchema());
529+
530+
// Test that explicitly set MIME type is not overridden
531+
$config2 = new ModelConfig();
532+
$config2->setOutputMimeType('text/plain');
533+
$config2->setOutputSchema($schema);
534+
535+
$this->assertEquals('text/plain', $config2->getOutputMimeType());
536+
$this->assertEquals($schema, $config2->getOutputSchema());
537+
}
538+
485539
/**
486540
* Tests setCustomOption method.
487541
*

0 commit comments

Comments
 (0)