From 0b8c2a1e18410115f5bbe9ba00b30908a77c9bc5 Mon Sep 17 00:00:00 2001 From: Lukas Schaefer Date: Wed, 9 Apr 2025 09:59:21 -0400 Subject: [PATCH 1/2] Fix registration validation Signed-off-by: Lukas Schaefer --- .../ProvidersAI/TaskProcessingService.php | 22 +++++++++++++------ 1 file changed, 15 insertions(+), 7 deletions(-) diff --git a/lib/Service/ProvidersAI/TaskProcessingService.php b/lib/Service/ProvidersAI/TaskProcessingService.php index d0fbcdd4..852735ab 100644 --- a/lib/Service/ProvidersAI/TaskProcessingService.php +++ b/lib/Service/ProvidersAI/TaskProcessingService.php @@ -79,7 +79,7 @@ public function getExAppTaskProcessingProvider(string $appId, string $name): ?Ta } } - private function everyElementHasKeys(array|null $array, array $keys): bool { + private function everyElementHasKeys(array|null $array, array $keys, bool $properties_have_array=true): bool { if (!is_array($array)) { return false; } @@ -88,12 +88,20 @@ private function everyElementHasKeys(array|null $array, array $keys): bool { if (!is_string($propertyName) || !is_array($properties)) { return false; } - foreach ($properties as $property) { - if (!is_array($property)) { - return false; + if ($properties_have_array) { + foreach ($properties as $property) { + if (!is_array($property)) { + return false; + } + foreach ($keys as $key) { + if (!array_key_exists($key, $property)) { + return false; + } + } } + } else { foreach ($keys as $key) { - if (!array_key_exists($key, $property)) { + if (!array_key_exists($key, $properties)) { return false; } } @@ -116,10 +124,10 @@ private function validateTaskProcessingProvider(array $provider): void { if (!isset($provider['expected_runtime']) || !is_int($provider['expected_runtime'])) { throw new Exception('"expected_runtime" key must be an integer'); } - if (!$this->everyElementHasKeys($provider['optional_input_shape'], ['name', 'description', 'shape_type'])) { + if (!$this->everyElementHasKeys($provider['optional_input_shape'], ['name', 'description', 'shape_type'], false)) { throw new Exception('"optional_input_shape" should be an array and must have "name", "description" and "shape_type" keys'); } - if (!$this->everyElementHasKeys($provider['optional_output_shape'], ['name', 'description', 'shape_type'])) { + if (!$this->everyElementHasKeys($provider['optional_output_shape'], ['name', 'description', 'shape_type'], false)) { throw new Exception('"optional_output_shape" should be an array and must have "name", "description" and "shape_type" keys'); } if (!$this->everyElementHasKeys($provider['input_shape_enum_values'], ['name', 'value'])) { From 73cb8d89ba6b6e2897fc6e89d1200a2d9c10c7f5 Mon Sep 17 00:00:00 2001 From: Lukas Schaefer Date: Thu, 10 Apr 2025 09:30:11 -0400 Subject: [PATCH 2/2] Validate like nc_py_api wants it and transform result correctly for assistant Signed-off-by: Lukas Schaefer --- .../ProvidersAI/TaskProcessingService.php | 51 +++++++++++-------- 1 file changed, 30 insertions(+), 21 deletions(-) diff --git a/lib/Service/ProvidersAI/TaskProcessingService.php b/lib/Service/ProvidersAI/TaskProcessingService.php index 852735ab..24e5f5a3 100644 --- a/lib/Service/ProvidersAI/TaskProcessingService.php +++ b/lib/Service/ProvidersAI/TaskProcessingService.php @@ -79,7 +79,7 @@ public function getExAppTaskProcessingProvider(string $appId, string $name): ?Ta } } - private function everyElementHasKeys(array|null $array, array $keys, bool $properties_have_array=true): bool { + private function everyElementHasKeys(array|null $array, array $keys): bool { if (!is_array($array)) { return false; } @@ -88,20 +88,12 @@ private function everyElementHasKeys(array|null $array, array $keys, bool $prope if (!is_string($propertyName) || !is_array($properties)) { return false; } - if ($properties_have_array) { - foreach ($properties as $property) { - if (!is_array($property)) { - return false; - } - foreach ($keys as $key) { - if (!array_key_exists($key, $property)) { - return false; - } - } + foreach ($properties as $property) { + if (!is_array($property)) { + return false; } - } else { foreach ($keys as $key) { - if (!array_key_exists($key, $properties)) { + if (!array_key_exists($key, $property)) { return false; } } @@ -111,6 +103,21 @@ private function everyElementHasKeys(array|null $array, array $keys, bool $prope return true; } + private function everyArrayElementHasKeys(array|null $array, array $keys): bool { + if (!is_array($array)) { + return false; + } + + foreach ($array as $element) { + foreach ($keys as $key) { + if (!array_key_exists($key, $element)) { + return false; + } + } + } + return true; + } + private function validateTaskProcessingProvider(array $provider): void { if (!isset($provider['id']) || !is_string($provider['id'])) { throw new Exception('"id" key must be a string'); @@ -124,10 +131,10 @@ private function validateTaskProcessingProvider(array $provider): void { if (!isset($provider['expected_runtime']) || !is_int($provider['expected_runtime'])) { throw new Exception('"expected_runtime" key must be an integer'); } - if (!$this->everyElementHasKeys($provider['optional_input_shape'], ['name', 'description', 'shape_type'], false)) { + if (!$this->everyArrayElementHasKeys($provider['optional_input_shape'], ['name', 'description', 'shape_type'])) { throw new Exception('"optional_input_shape" should be an array and must have "name", "description" and "shape_type" keys'); } - if (!$this->everyElementHasKeys($provider['optional_output_shape'], ['name', 'description', 'shape_type'], false)) { + if (!$this->everyArrayElementHasKeys($provider['optional_output_shape'], ['name', 'description', 'shape_type'])) { throw new Exception('"optional_output_shape" should be an array and must have "name", "description" and "shape_type" keys'); } if (!$this->everyElementHasKeys($provider['input_shape_enum_values'], ['name', 'value'])) { @@ -278,23 +285,25 @@ public function getExpectedRuntime(): int { } public function getOptionalInputShape(): array { - return array_map(function ($shape) { - return new ShapeDescriptor( + return array_reduce($this->provider['optional_input_shape'], function (array $input, array $shape) { + $input[$shape['name']] = new ShapeDescriptor( $shape['name'], $shape['description'], EShapeType::from($shape['shape_type']), ); - }, $this->provider['optional_input_shape']); + return $input; + }, []); } public function getOptionalOutputShape(): array { - return array_map(static function (array $shape) { - return new ShapeDescriptor( + return array_reduce($this->provider['optional_output_shape'], function (array $input, array $shape) { + $input[$shape['name']] = new ShapeDescriptor( $shape['name'], $shape['description'], EShapeType::from($shape['shape_type']), ); - }, $this->provider['optional_output_shape']); + return $input; + }, []); } public function getInputShapeEnumValues(): array {