diff --git a/README.md b/README.md index 32138174..0a353e7c 100644 --- a/README.md +++ b/README.md @@ -53,7 +53,7 @@ Provided Tools * [x] SerpApi * [x] Clock * [x] Wikipedia -* [ ] Weather +* [x] Weather Usage Examples -------------- diff --git a/examples/toolchain-weather.php b/examples/toolchain-weather.php new file mode 100755 index 00000000..1be8649b --- /dev/null +++ b/examples/toolchain-weather.php @@ -0,0 +1,28 @@ +call($messages); + +echo $response.PHP_EOL; diff --git a/src/ToolBox/Metadata.php b/src/ToolBox/Metadata.php index d55ef8db..d6c94d2e 100644 --- a/src/ToolBox/Metadata.php +++ b/src/ToolBox/Metadata.php @@ -7,7 +7,7 @@ /** * @phpstan-import-type ParameterDefinition from ParameterAnalyzer */ -final class Metadata +final class Metadata implements \JsonSerializable { /** * @param ParameterDefinition|null $parameters @@ -20,4 +20,31 @@ public function __construct( public readonly ?array $parameters, ) { } + + /** + * @return array{ + * type: 'function', + * function: array{ + * name: string, + * description: string, + * parameters?: ParameterDefinition + * } + * } + */ + public function jsonSerialize(): array + { + $function = [ + 'name' => $this->name, + 'description' => $this->description, + ]; + + if (isset($this->parameters)) { + $function['parameters'] = $this->parameters; + } + + return [ + 'type' => 'function', + 'function' => $function, + ]; + } } diff --git a/src/ToolBox/ParameterAnalyzer.php b/src/ToolBox/ParameterAnalyzer.php index 5587541d..1f7849a5 100644 --- a/src/ToolBox/ParameterAnalyzer.php +++ b/src/ToolBox/ParameterAnalyzer.php @@ -40,6 +40,10 @@ public function getDefinition(string $className, string $methodName): ?array $paramType = 'integer'; } + if ('float' === $paramType) { + $paramType = 'number'; + } + if (!$parameter->isOptional()) { $result['required'][] = $paramName; } diff --git a/src/ToolBox/Registry.php b/src/ToolBox/Registry.php index 809c619b..da67c8a8 100644 --- a/src/ToolBox/Registry.php +++ b/src/ToolBox/Registry.php @@ -6,9 +6,6 @@ use PhpLlm\LlmChain\Response\ToolCall; -/** - * @phpstan-import-type ToolDefinition from RegistryInterface - */ final class Registry implements RegistryInterface { /** @@ -17,7 +14,7 @@ final class Registry implements RegistryInterface private readonly array $tools; /** - * @var list + * @var Metadata[] */ private array $map; @@ -40,19 +37,7 @@ public function getMap(): array $map = []; foreach ($this->tools as $tool) { foreach ($this->toolAnalyzer->getMetadata($tool::class) as $metadata) { - $function = [ - 'name' => $metadata->name, - 'description' => $metadata->description, - ]; - - if (isset($metadata->parameters)) { - $function['parameters'] = $metadata->parameters; - } - - $map[] = [ - 'type' => 'function', - 'function' => $function, - ]; + $map[] = $metadata; } } diff --git a/src/ToolBox/RegistryInterface.php b/src/ToolBox/RegistryInterface.php index b0646fca..57c1a29a 100644 --- a/src/ToolBox/RegistryInterface.php +++ b/src/ToolBox/RegistryInterface.php @@ -6,22 +6,10 @@ use PhpLlm\LlmChain\Response\ToolCall; -/** - * @phpstan-import-type ParameterDefinition from ParameterAnalyzer - * - * @phpstan-type ToolDefinition = array{ - * type: 'function', - * function: array{ - * name: string, - * description: string, - * parameters?: ParameterDefinition - * } - * } - */ interface RegistryInterface { /** - * @return list + * @return Metadata[] */ public function getMap(): array; diff --git a/src/ToolBox/Tool/OpenMeteo.php b/src/ToolBox/Tool/OpenMeteo.php new file mode 100644 index 00000000..9823de5c --- /dev/null +++ b/src/ToolBox/Tool/OpenMeteo.php @@ -0,0 +1,34 @@ +httpClient->request('GET', 'https://api.open-meteo.com/v1/forecast', [ + 'query' => [ + 'latitude' => $latitude, + 'longitude' => $longitude, + 'current' => 'temperature_2m,wind_speed_10m', + ], + ]); + + return $response->getContent(); + } +} diff --git a/tests/ToolBox/RegistryTest.php b/tests/ToolBox/RegistryTest.php index 7fdaf218..42436573 100644 --- a/tests/ToolBox/RegistryTest.php +++ b/tests/ToolBox/RegistryTest.php @@ -89,7 +89,7 @@ public function testFunctionsMap(): void ], ]; - self::assertSame($expected, $actual); + self::assertSame(json_encode($expected), json_encode($actual)); } public function testExecute(): void