Skip to content

Commit b0cacfb

Browse files
authored
Merge pull request #58 from WordPress/fix-function-dtos
Fixes Function Call and Declaration DTOs
2 parents ef7d83a + 668119c commit b0cacfb

File tree

4 files changed

+36
-37
lines changed

4 files changed

+36
-37
lines changed

src/Tools/DTO/FunctionCall.php

Lines changed: 10 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@
1515
*
1616
* @since n.e.x.t
1717
*
18-
* @phpstan-type FunctionCallArrayShape array{id?: string, name?: string, args?: array<string, mixed>}
18+
* @phpstan-type FunctionCallArrayShape array{id?: string, name?: string, args?: mixed}
1919
*
2020
* @extends AbstractDataTransferObject<FunctionCallArrayShape>
2121
*/
@@ -35,9 +35,9 @@ class FunctionCall extends AbstractDataTransferObject
3535
private ?string $name;
3636

3737
/**
38-
* @var array<string, mixed> The arguments to pass to the function.
38+
* @var mixed The arguments to pass to the function.
3939
*/
40-
private array $args;
40+
private $args;
4141

4242
/**
4343
* Constructor.
@@ -46,10 +46,10 @@ class FunctionCall extends AbstractDataTransferObject
4646
*
4747
* @param string|null $id Unique identifier for this function call.
4848
* @param string|null $name The name of the function to call.
49-
* @param array<string, mixed> $args The arguments to pass to the function.
49+
* @param mixed $args The arguments to pass to the function.
5050
* @throws InvalidArgumentException If neither id nor name is provided.
5151
*/
52-
public function __construct(?string $id = null, ?string $name = null, array $args = [])
52+
public function __construct(?string $id = null, ?string $name = null, $args = null)
5353
{
5454
if ($id === null && $name === null) {
5555
throw new InvalidArgumentException('At least one of id or name must be provided.');
@@ -89,9 +89,9 @@ public function getName(): ?string
8989
*
9090
* @since n.e.x.t
9191
*
92-
* @return array<string, mixed> The function arguments.
92+
* @return mixed The function arguments.
9393
*/
94-
public function getArgs(): array
94+
public function getArgs()
9595
{
9696
return $this->args;
9797
}
@@ -115,9 +115,8 @@ public static function getJsonSchema(): array
115115
'description' => 'The name of the function to call.',
116116
],
117117
self::KEY_ARGS => [
118-
'type' => 'object',
118+
'type' => ['string', 'number', 'boolean', 'object', 'array', 'null'],
119119
'description' => 'The arguments to pass to the function.',
120-
'additionalProperties' => true,
121120
],
122121
],
123122
'oneOf' => [
@@ -150,7 +149,7 @@ public function toArray(): array
150149
$data[self::KEY_NAME] = $this->name;
151150
}
152151

153-
if (!empty($this->args)) {
152+
if ($this->args !== null) {
154153
$data[self::KEY_ARGS] = $this->args;
155154
}
156155

@@ -167,7 +166,7 @@ public static function fromArray(array $array): self
167166
return new self(
168167
$array[self::KEY_ID] ?? null,
169168
$array[self::KEY_NAME] ?? null,
170-
$array[self::KEY_ARGS] ?? []
169+
$array[self::KEY_ARGS] ?? null
171170
);
172171
}
173172
}

src/Tools/DTO/FunctionDeclaration.php

Lines changed: 13 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,11 @@
1414
*
1515
* @since n.e.x.t
1616
*
17-
* @phpstan-type FunctionDeclarationArrayShape array{name: string, description: string, parameters?: mixed}
17+
* @phpstan-type FunctionDeclarationArrayShape array{
18+
* name: string,
19+
* description: string,
20+
* parameters?: array<string, mixed>
21+
* }
1822
*
1923
* @extends AbstractDataTransferObject<FunctionDeclarationArrayShape>
2024
*/
@@ -34,9 +38,9 @@ class FunctionDeclaration extends AbstractDataTransferObject
3438
private string $description;
3539

3640
/**
37-
* @var mixed|null The JSON schema for the function parameters.
41+
* @var array<string, mixed>|null The JSON schema for the function parameters.
3842
*/
39-
private $parameters;
43+
private ?array $parameters;
4044

4145
/**
4246
* Constructor.
@@ -45,9 +49,9 @@ class FunctionDeclaration extends AbstractDataTransferObject
4549
*
4650
* @param string $name The name of the function.
4751
* @param string $description A description of what the function does.
48-
* @param mixed $parameters The JSON schema for the function parameters.
52+
* @param array<string, mixed>|null $parameters The JSON schema for the function parameters.
4953
*/
50-
public function __construct(string $name, string $description, $parameters = null)
54+
public function __construct(string $name, string $description, ?array $parameters = null)
5155
{
5256
$this->name = $name;
5357
$this->description = $description;
@@ -83,9 +87,9 @@ public function getDescription(): string
8387
*
8488
* @since n.e.x.t
8589
*
86-
* @return mixed|null The parameters schema.
90+
* @return array<string, mixed>|null The parameters schema.
8791
*/
88-
public function getParameters()
92+
public function getParameters(): ?array
8993
{
9094
return $this->parameters;
9195
}
@@ -109,8 +113,9 @@ public static function getJsonSchema(): array
109113
'description' => 'A description of what the function does.',
110114
],
111115
self::KEY_PARAMETERS => [
112-
'type' => ['string', 'number', 'boolean', 'object', 'array', 'null'],
116+
'type' => 'object',
113117
'description' => 'The JSON schema for the function parameters.',
118+
'additionalProperties' => true,
114119
],
115120
],
116121
'required' => [self::KEY_NAME, self::KEY_DESCRIPTION],

tests/unit/Tools/DTO/FunctionCallTest.php

Lines changed: 10 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -76,7 +76,7 @@ public function testCreateWithoutArgs(): void
7676

7777
$this->assertEquals('func_123', $functionCall->getId());
7878
$this->assertEquals('getTime', $functionCall->getName());
79-
$this->assertEquals([], $functionCall->getArgs());
79+
$this->assertNull($functionCall->getArgs());
8080
}
8181

8282
/**
@@ -118,9 +118,14 @@ public function testJsonSchema(): void
118118
$this->assertEquals('string', $schema['properties'][FunctionCall::KEY_NAME]['type']);
119119
$this->assertArrayHasKey('description', $schema['properties'][FunctionCall::KEY_NAME]);
120120

121-
// Check args property
122-
$this->assertEquals('object', $schema['properties'][FunctionCall::KEY_ARGS]['type']);
123-
$this->assertTrue($schema['properties'][FunctionCall::KEY_ARGS]['additionalProperties']);
121+
// Check args property - can be any type
122+
$this->assertIsArray($schema['properties'][FunctionCall::KEY_ARGS]['type']);
123+
$this->assertContains('string', $schema['properties'][FunctionCall::KEY_ARGS]['type']);
124+
$this->assertContains('number', $schema['properties'][FunctionCall::KEY_ARGS]['type']);
125+
$this->assertContains('boolean', $schema['properties'][FunctionCall::KEY_ARGS]['type']);
126+
$this->assertContains('object', $schema['properties'][FunctionCall::KEY_ARGS]['type']);
127+
$this->assertContains('array', $schema['properties'][FunctionCall::KEY_ARGS]['type']);
128+
$this->assertContains('null', $schema['properties'][FunctionCall::KEY_ARGS]['type']);
124129

125130
// Check oneOf for required fields
126131
$this->assertArrayHasKey('oneOf', $schema);
@@ -243,7 +248,7 @@ public function testFromArrayMinimalFields(): void
243248
$this->assertInstanceOf(FunctionCall::class, $functionCall);
244249
$this->assertNull($functionCall->getId());
245250
$this->assertEquals('minimal', $functionCall->getName());
246-
$this->assertEquals([], $functionCall->getArgs());
251+
$this->assertNull($functionCall->getArgs());
247252
}
248253

249254
/**

tests/unit/Tools/DTO/FunctionDeclarationTest.php

Lines changed: 3 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -80,12 +80,7 @@ public function parameterTypesProvider(): array
8080
{
8181
return [
8282
'null' => [null],
83-
'string' => ['simple string parameter'],
84-
'number' => [42],
85-
'float' => [3.14],
86-
'boolean' => [true],
8783
'array' => [['key' => 'value']],
88-
'object' => [(object) ['property' => 'value']],
8984
'complex schema' => [[
9085
'type' => 'object',
9186
'properties' => [
@@ -127,14 +122,9 @@ public function testJsonSchema(): void
127122
$this->assertArrayHasKey('description', $schema['properties'][FunctionDeclaration::KEY_DESCRIPTION]);
128123

129124
// Check parameters property allows multiple types
130-
$paramTypes = $schema['properties'][FunctionDeclaration::KEY_PARAMETERS]['type'];
131-
$this->assertIsArray($paramTypes);
132-
$this->assertContains('string', $paramTypes);
133-
$this->assertContains('number', $paramTypes);
134-
$this->assertContains('boolean', $paramTypes);
135-
$this->assertContains('object', $paramTypes);
136-
$this->assertContains('array', $paramTypes);
137-
$this->assertContains('null', $paramTypes);
125+
// Parameters should be object type (for JSON schema)
126+
$this->assertEquals('object', $schema['properties'][FunctionDeclaration::KEY_PARAMETERS]['type']);
127+
$this->assertTrue($schema['properties'][FunctionDeclaration::KEY_PARAMETERS]['additionalProperties']);
138128

139129
// Check required fields - parameters should NOT be required
140130
$this->assertArrayHasKey('required', $schema);

0 commit comments

Comments
 (0)