Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
21 changes: 10 additions & 11 deletions src/Tools/DTO/FunctionCall.php
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@
*
* @since n.e.x.t
*
* @phpstan-type FunctionCallArrayShape array{id?: string, name?: string, args?: array<string, mixed>}
* @phpstan-type FunctionCallArrayShape array{id?: string, name?: string, args?: mixed}
*
* @extends AbstractDataTransferObject<FunctionCallArrayShape>
*/
Expand All @@ -35,9 +35,9 @@ class FunctionCall extends AbstractDataTransferObject
private ?string $name;

/**
* @var array<string, mixed> The arguments to pass to the function.
* @var mixed The arguments to pass to the function.
*/
private array $args;
private $args;

/**
* Constructor.
Expand All @@ -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<string, mixed> $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.');
Expand Down Expand Up @@ -89,9 +89,9 @@ public function getName(): ?string
*
* @since n.e.x.t
*
* @return array<string, mixed> The function arguments.
* @return mixed The function arguments.
*/
public function getArgs(): array
public function getArgs()
{
return $this->args;
}
Expand All @@ -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' => [
Expand Down Expand Up @@ -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;
}

Expand All @@ -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
);
}
}
21 changes: 13 additions & 8 deletions src/Tools/DTO/FunctionDeclaration.php
Original file line number Diff line number Diff line change
Expand Up @@ -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<string, mixed>
* }
*
* @extends AbstractDataTransferObject<FunctionDeclarationArrayShape>
*/
Expand All @@ -34,9 +38,9 @@ class FunctionDeclaration extends AbstractDataTransferObject
private string $description;

/**
* @var mixed|null The JSON schema for the function parameters.
* @var array<string, mixed>|null The JSON schema for the function parameters.
*/
private $parameters;
private ?array $parameters;

/**
* Constructor.
Expand All @@ -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<string, mixed>|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;
Expand Down Expand Up @@ -83,9 +87,9 @@ public function getDescription(): string
*
* @since n.e.x.t
*
* @return mixed|null The parameters schema.
* @return array<string, mixed>|null The parameters schema.
*/
public function getParameters()
public function getParameters(): ?array
{
return $this->parameters;
}
Expand All @@ -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],
Expand Down
15 changes: 10 additions & 5 deletions tests/unit/Tools/DTO/FunctionCallTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -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());
}

/**
Expand Down Expand Up @@ -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);
Expand Down Expand Up @@ -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());
}

/**
Expand Down
16 changes: 3 additions & 13 deletions tests/unit/Tools/DTO/FunctionDeclarationTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -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' => [
Expand Down Expand Up @@ -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);
Expand Down