tools ) { return []; } return parent::filterToolsRequiringApproval( $runnable ); } /** * Required properties the model left out of the call entirely. * * Matches Tool::execute()'s own rule (array_key_exists, not empty) so this * flags exactly the calls that would have thrown, and nothing else — an * explicit null or empty string is the tool's own business to validate. * * @param ToolInterface $tool Tool to inspect. * @return string[] Missing required property names. */ private static function missing_required_inputs( ToolInterface $tool ): array { $inputs = $tool->getInputs(); $missing = []; foreach ( $tool->getProperties() as $property ) { if ( $property->isRequired() && ! array_key_exists( $property->getName(), $inputs ) ) { $missing[] = $property->getName(); } } return $missing; } /** * Turn a malformed call into a corrective tool result. * * The missing keys are backfilled with null purely so Tool::execute() gets * past its own required-parameter check and reaches the callback — without * them it throws before any callback runs and the turn is lost again. * * @param ToolInterface $tool Tool to neutralize. * @param string[] $missing Missing required property names. * @return void */ private static function neutralize( ToolInterface $tool, array $missing ): void { $tool->setInputs( array_merge( array_fill_keys( $missing, null ), $tool->getInputs() ) ); $message = sprintf( /* translators: 1: tool name, 2: comma-separated list of argument names. */ __( 'TOOL NOT EXECUTED. The call to "%1$s" was missing required argument(s): %2$s. Nothing was created or changed. Re-issue the call with every required argument filled in, asking the user for any value you cannot determine.', 'aisentic' ), $tool->getName(), implode( ', ', $missing ) ); $tool->setCallable( new ToolRejectionHandler( $message ) ); } }