From 9e6a1a509765b923c789e169f1c9f6ba8874c626 Mon Sep 17 00:00:00 2001 From: Jason Adams Date: Thu, 21 Aug 2025 16:44:43 -0600 Subject: [PATCH 1/2] fix: corrects function call and declaration args --- src/Tools/DTO/FunctionCall.php | 21 ++++++++++----------- src/Tools/DTO/FunctionDeclaration.php | 21 +++++++++++++-------- tests/unit/Tools/DTO/FunctionCallTest.php | 15 ++++++++++----- 3 files changed, 33 insertions(+), 24 deletions(-) diff --git a/src/Tools/DTO/FunctionCall.php b/src/Tools/DTO/FunctionCall.php index 51371a52..a98761f8 100644 --- a/src/Tools/DTO/FunctionCall.php +++ b/src/Tools/DTO/FunctionCall.php @@ -15,7 +15,7 @@ * * @since n.e.x.t * - * @phpstan-type FunctionCallArrayShape array{id?: string, name?: string, args?: array} + * @phpstan-type FunctionCallArrayShape array{id?: string, name?: string, args?: mixed} * * @extends AbstractDataTransferObject */ @@ -35,9 +35,9 @@ class FunctionCall extends AbstractDataTransferObject private ?string $name; /** - * @var array The arguments to pass to the function. + * @var mixed The arguments to pass to the function. */ - private array $args; + private $args; /** * Constructor. @@ -46,10 +46,10 @@ class FunctionCall extends AbstractDataTransferObject * * @param string|null $id Unique identifier for this function call. * @param string|null $name The name of the function to call. - * @param array $args The arguments to pass to the function. + * @param mixed $args The arguments to pass to the function. * @throws InvalidArgumentException If neither id nor name is provided. */ - public function __construct(?string $id = null, ?string $name = null, array $args = []) + public function __construct(?string $id = null, ?string $name = null, $args = null) { if ($id === null && $name === null) { throw new InvalidArgumentException('At least one of id or name must be provided.'); @@ -89,9 +89,9 @@ public function getName(): ?string * * @since n.e.x.t * - * @return array The function arguments. + * @return mixed The function arguments. */ - public function getArgs(): array + public function getArgs() { return $this->args; } @@ -115,9 +115,8 @@ public static function getJsonSchema(): array 'description' => 'The name of the function to call.', ], self::KEY_ARGS => [ - 'type' => 'object', + 'type' => ['string', 'number', 'boolean', 'object', 'array', 'null'], 'description' => 'The arguments to pass to the function.', - 'additionalProperties' => true, ], ], 'oneOf' => [ @@ -150,7 +149,7 @@ public function toArray(): array $data[self::KEY_NAME] = $this->name; } - if (!empty($this->args)) { + if ($this->args !== null) { $data[self::KEY_ARGS] = $this->args; } @@ -167,7 +166,7 @@ public static function fromArray(array $array): self return new self( $array[self::KEY_ID] ?? null, $array[self::KEY_NAME] ?? null, - $array[self::KEY_ARGS] ?? [] + $array[self::KEY_ARGS] ?? null ); } } diff --git a/src/Tools/DTO/FunctionDeclaration.php b/src/Tools/DTO/FunctionDeclaration.php index 7614ed2d..66c024b1 100644 --- a/src/Tools/DTO/FunctionDeclaration.php +++ b/src/Tools/DTO/FunctionDeclaration.php @@ -14,7 +14,11 @@ * * @since n.e.x.t * - * @phpstan-type FunctionDeclarationArrayShape array{name: string, description: string, parameters?: mixed} + * @phpstan-type FunctionDeclarationArrayShape array{ + * name: string, + * description: string, + * parameters?: array + * } * * @extends AbstractDataTransferObject */ @@ -34,9 +38,9 @@ class FunctionDeclaration extends AbstractDataTransferObject private string $description; /** - * @var mixed|null The JSON schema for the function parameters. + * @var array|null The JSON schema for the function parameters. */ - private $parameters; + private ?array $parameters; /** * Constructor. @@ -45,9 +49,9 @@ class FunctionDeclaration extends AbstractDataTransferObject * * @param string $name The name of the function. * @param string $description A description of what the function does. - * @param mixed $parameters The JSON schema for the function parameters. + * @param array|null $parameters The JSON schema for the function parameters. */ - public function __construct(string $name, string $description, $parameters = null) + public function __construct(string $name, string $description, ?array $parameters = null) { $this->name = $name; $this->description = $description; @@ -83,9 +87,9 @@ public function getDescription(): string * * @since n.e.x.t * - * @return mixed|null The parameters schema. + * @return array|null The parameters schema. */ - public function getParameters() + public function getParameters(): ?array { return $this->parameters; } @@ -109,8 +113,9 @@ public static function getJsonSchema(): array 'description' => 'A description of what the function does.', ], self::KEY_PARAMETERS => [ - 'type' => ['string', 'number', 'boolean', 'object', 'array', 'null'], + 'type' => 'object', 'description' => 'The JSON schema for the function parameters.', + 'additionalProperties' => true, ], ], 'required' => [self::KEY_NAME, self::KEY_DESCRIPTION], diff --git a/tests/unit/Tools/DTO/FunctionCallTest.php b/tests/unit/Tools/DTO/FunctionCallTest.php index 40744522..12095d96 100644 --- a/tests/unit/Tools/DTO/FunctionCallTest.php +++ b/tests/unit/Tools/DTO/FunctionCallTest.php @@ -76,7 +76,7 @@ public function testCreateWithoutArgs(): void $this->assertEquals('func_123', $functionCall->getId()); $this->assertEquals('getTime', $functionCall->getName()); - $this->assertEquals([], $functionCall->getArgs()); + $this->assertNull($functionCall->getArgs()); } /** @@ -118,9 +118,14 @@ public function testJsonSchema(): void $this->assertEquals('string', $schema['properties'][FunctionCall::KEY_NAME]['type']); $this->assertArrayHasKey('description', $schema['properties'][FunctionCall::KEY_NAME]); - // Check args property - $this->assertEquals('object', $schema['properties'][FunctionCall::KEY_ARGS]['type']); - $this->assertTrue($schema['properties'][FunctionCall::KEY_ARGS]['additionalProperties']); + // Check args property - can be any type + $this->assertIsArray($schema['properties'][FunctionCall::KEY_ARGS]['type']); + $this->assertContains('string', $schema['properties'][FunctionCall::KEY_ARGS]['type']); + $this->assertContains('number', $schema['properties'][FunctionCall::KEY_ARGS]['type']); + $this->assertContains('boolean', $schema['properties'][FunctionCall::KEY_ARGS]['type']); + $this->assertContains('object', $schema['properties'][FunctionCall::KEY_ARGS]['type']); + $this->assertContains('array', $schema['properties'][FunctionCall::KEY_ARGS]['type']); + $this->assertContains('null', $schema['properties'][FunctionCall::KEY_ARGS]['type']); // Check oneOf for required fields $this->assertArrayHasKey('oneOf', $schema); @@ -243,7 +248,7 @@ public function testFromArrayMinimalFields(): void $this->assertInstanceOf(FunctionCall::class, $functionCall); $this->assertNull($functionCall->getId()); $this->assertEquals('minimal', $functionCall->getName()); - $this->assertEquals([], $functionCall->getArgs()); + $this->assertNull($functionCall->getArgs()); } /** From 668119cb6e40e9797f07a682733c05367bcec8f5 Mon Sep 17 00:00:00 2001 From: Jason Adams Date: Thu, 21 Aug 2025 16:54:29 -0600 Subject: [PATCH 2/2] test: fixes old, now invalid args --- tests/unit/Tools/DTO/FunctionDeclarationTest.php | 16 +++------------- 1 file changed, 3 insertions(+), 13 deletions(-) diff --git a/tests/unit/Tools/DTO/FunctionDeclarationTest.php b/tests/unit/Tools/DTO/FunctionDeclarationTest.php index b5322f2a..b2782bdb 100644 --- a/tests/unit/Tools/DTO/FunctionDeclarationTest.php +++ b/tests/unit/Tools/DTO/FunctionDeclarationTest.php @@ -80,12 +80,7 @@ public function parameterTypesProvider(): array { return [ 'null' => [null], - 'string' => ['simple string parameter'], - 'number' => [42], - 'float' => [3.14], - 'boolean' => [true], 'array' => [['key' => 'value']], - 'object' => [(object) ['property' => 'value']], 'complex schema' => [[ 'type' => 'object', 'properties' => [ @@ -127,14 +122,9 @@ public function testJsonSchema(): void $this->assertArrayHasKey('description', $schema['properties'][FunctionDeclaration::KEY_DESCRIPTION]); // Check parameters property allows multiple types - $paramTypes = $schema['properties'][FunctionDeclaration::KEY_PARAMETERS]['type']; - $this->assertIsArray($paramTypes); - $this->assertContains('string', $paramTypes); - $this->assertContains('number', $paramTypes); - $this->assertContains('boolean', $paramTypes); - $this->assertContains('object', $paramTypes); - $this->assertContains('array', $paramTypes); - $this->assertContains('null', $paramTypes); + // Parameters should be object type (for JSON schema) + $this->assertEquals('object', $schema['properties'][FunctionDeclaration::KEY_PARAMETERS]['type']); + $this->assertTrue($schema['properties'][FunctionDeclaration::KEY_PARAMETERS]['additionalProperties']); // Check required fields - parameters should NOT be required $this->assertArrayHasKey('required', $schema);