mirror of
https://github.com/Karaka-Management/Build.git
synced 2026-01-11 11:48:40 +00:00
testing with chatGPT as autoGpt code helper
This commit is contained in:
parent
6e4af6d23a
commit
f934a76bf9
115
Helper/GptHelper.php
Normal file
115
Helper/GptHelper.php
Normal file
|
|
@ -0,0 +1,115 @@
|
|||
<?php
|
||||
|
||||
namespace Build\Helper;
|
||||
|
||||
use phpOMS\Message\Http\HttpRequest;
|
||||
use phpOMS\Message\Http\Rest;
|
||||
use phpOMS\Uri\HttpUri;
|
||||
|
||||
class GptHelper
|
||||
{
|
||||
private const ENDPOINT = 'https://api.openai.com/v1/chat/completions';
|
||||
private const APIKEY = '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';
|
||||
private const MODEL = 'gpt-3.5-turbo';
|
||||
private const TEMPERATUR = 0.9;
|
||||
private const MAX_TOKENS = 3096;
|
||||
private const MAX_STRLEN = 1500;
|
||||
|
||||
private const LIMIT_REQUEST_PER_MINUTE = 3;
|
||||
private const LIMIT_TOKENS_PER_MINUTE = 40000;
|
||||
|
||||
private static $lastRun = 0;
|
||||
|
||||
public static function defaultFileReader($in, $filename)
|
||||
{
|
||||
return \fgets($in);
|
||||
}
|
||||
|
||||
public static function aiRequest(string $behavior, string $content) : string
|
||||
{
|
||||
if (\trim($content) === '') {
|
||||
return '';
|
||||
}
|
||||
|
||||
$requestBody = [
|
||||
'model' => self::MODEL,
|
||||
'max_tokens' => self::MAX_TOKENS,
|
||||
'temperature' => self::TEMPERATUR,
|
||||
'messages' => [
|
||||
[
|
||||
'role' => 'system',
|
||||
'content' => $behavior,
|
||||
],
|
||||
[
|
||||
'role' => 'user',
|
||||
'content' => $content,
|
||||
]
|
||||
]
|
||||
];
|
||||
|
||||
$request = new HttpRequest(new HttpUri(self::ENDPOINT));
|
||||
$request->header->set('Authorization', 'Bearer ' . self::APIKEY);
|
||||
$request->header->set('Content-Type', 'application/json');
|
||||
$request->setMethod('POST');
|
||||
$request->fromData($requestBody);
|
||||
|
||||
$time = \time();
|
||||
if ($time - self::$lastRun < 61 / self::LIMIT_REQUEST_PER_MINUTE) {
|
||||
\sleep(61 / self::LIMIT_REQUEST_PER_MINUTE - ($time - self::$lastRun));
|
||||
}
|
||||
|
||||
$response = Rest::request($request);
|
||||
self::$lastRun = \time();
|
||||
|
||||
return $response->getBody();
|
||||
}
|
||||
|
||||
public static function handleFile(string $inPath, string $outPath, string $behavior, \Closure $fileReader) : string
|
||||
{
|
||||
$response = '';
|
||||
|
||||
$in = \fopen($inPath, 'r');
|
||||
$out = \fopen($outPath . ($inPath === $outPath ? '.out' : ''), 'w');
|
||||
$lines = '';
|
||||
|
||||
while (($line = $fileReader($in, $inPath)) !== false) {
|
||||
if (\strlen($lines) > self::MAX_STRLEN) {
|
||||
$response = self::aiRequest($behavior, $lines);
|
||||
|
||||
if ($response === '') {
|
||||
continue;
|
||||
}
|
||||
|
||||
$json = \json_decode($response, true);
|
||||
\fwrite($out, \str_replace("\n\n", "\n", $json[5][0]['message']['content']));
|
||||
|
||||
$lines = '';
|
||||
}
|
||||
|
||||
$lines .= $line . "\n";
|
||||
}
|
||||
|
||||
if (\trim($lines) !== '') {
|
||||
$response = self::aiRequest($behavior, $lines);
|
||||
|
||||
if ($response !== '') {
|
||||
$json = \json_decode($response, true);
|
||||
\fwrite($out, \str_replace("\n\n", "\n", $json[5][0]['message']['content']));
|
||||
}
|
||||
}
|
||||
|
||||
\fwrite($out, "\n");
|
||||
|
||||
\fclose($in);
|
||||
|
||||
if ($outPath === 'php://memory') {
|
||||
\rewind($out);
|
||||
$response = \stream_get_contents($out);
|
||||
\fclose($out);
|
||||
}
|
||||
|
||||
\fclose($out);
|
||||
|
||||
return $response;
|
||||
}
|
||||
}
|
||||
243
Helper/autoGpt.php
Normal file
243
Helper/autoGpt.php
Normal file
|
|
@ -0,0 +1,243 @@
|
|||
<?php
|
||||
|
||||
use Build\Helper\GptHelper;
|
||||
|
||||
include __DIR__ . '/../../phpOMS/Autoloader.php';
|
||||
|
||||
// fix docblocks
|
||||
$globs = [
|
||||
__DIR__ . '/../../phpOMS/*.php',
|
||||
__DIR__ . '/../../Modules/*/Models/*.php',
|
||||
__DIR__ . '/../../Modules/*/Controller/*.php',
|
||||
];
|
||||
|
||||
$behaviour = <<<BEHAVIOUR
|
||||
Create missing php docblocks with a similar format for member variables:
|
||||
/**
|
||||
* Default delivery address.
|
||||
*
|
||||
* @var Address|null
|
||||
* @since 1.0.0
|
||||
*/
|
||||
and for functions:
|
||||
/**
|
||||
* Order contact elements
|
||||
*
|
||||
* @param ContactElement \$ele Element
|
||||
* @param bool \$isRequired Is required
|
||||
*
|
||||
* @return int
|
||||
*
|
||||
* @since 1.0.0
|
||||
*/
|
||||
BEHAVIOUR;
|
||||
|
||||
$fileReader = function ($in, $filename)
|
||||
{
|
||||
$lines = '';
|
||||
$scopeStart = false;
|
||||
$scopeCounter = 0;
|
||||
|
||||
while (($line = \fgets($in)) !== false && ($line !== '' || $scopeCounter > 0)) {
|
||||
if (\stripos($line, ' function ') !== false) {
|
||||
$scopeStart = true;
|
||||
}
|
||||
|
||||
if ($scopeStart) {
|
||||
$scopeCounter += \substr_count($line, '{');
|
||||
$scopeCounter -= \substr_count($line, '}');
|
||||
|
||||
if ($scopeCounter === 0) {
|
||||
$scopeStart = false;
|
||||
}
|
||||
}
|
||||
|
||||
$lines .= $line;
|
||||
}
|
||||
|
||||
return $lines;
|
||||
};
|
||||
|
||||
foreach ($globs as $glob) {
|
||||
$files = \glob($glob);
|
||||
|
||||
foreach ($files as $file) {
|
||||
if (\stripos($file, 'Test.php')) {
|
||||
continue;
|
||||
}
|
||||
|
||||
GptHelper::handleFile($file, $file, $behaviour, $fileReader);
|
||||
}
|
||||
}
|
||||
|
||||
// implement test
|
||||
$globs = [
|
||||
__DIR__ . '/../../phpOMS/*.php',
|
||||
__DIR__ . '/../../Modules/*/Models/*.php',
|
||||
];
|
||||
|
||||
$behaviour = <<<BEHAVIOUR
|
||||
Implement a php unit test for the given function.
|
||||
BEHAVIOUR;
|
||||
|
||||
$fileReader = function ($in, $filename)
|
||||
{
|
||||
$lines = '';
|
||||
$scopeStart = false;
|
||||
$scopeCounter = 0;
|
||||
|
||||
while (($line = \fgets($in)) !== false && ($line !== '' || $scopeCounter > 0)) {
|
||||
if (\stripos($line, 'public function ') !== false || \stripos($line, 'public static function ') !== false) {
|
||||
// Check if a test exists for this function
|
||||
$testFile = \str_replace('.php', 'Test.php', $filename);
|
||||
$testFile = \str_replace('/phpOMS/', '/phpOMS/tests/', $filename);
|
||||
|
||||
if (\stripos($testFile, '../Modules/') !== false) {
|
||||
$subdirectory = "tests/";
|
||||
|
||||
$position = strrpos($testFile, "/../");
|
||||
|
||||
if ($position !== false) {
|
||||
$position = \stripos($testFile, '/', $position + 4) + 1;
|
||||
$position = \stripos($testFile, '/', $position) + 1;
|
||||
$testFile = \substr_replace($testFile, $subdirectory, $position, 0);
|
||||
}
|
||||
}
|
||||
|
||||
if (\file_exists($testFile)) {
|
||||
$scopeStart = true;
|
||||
|
||||
$testContent = \file_get_contents($testFile);
|
||||
|
||||
// Parse functio name
|
||||
$pattern = '/\bfunction\b\s+(\w+)\s*\(/';
|
||||
\preg_match($pattern, $line, $matches);
|
||||
|
||||
if (\stripos($testContent, $matches[1] ?? '~~~') !== false) {
|
||||
// Test already exists
|
||||
$scopeStart = false;
|
||||
}
|
||||
}
|
||||
|
||||
$scopeStart = true;
|
||||
}
|
||||
|
||||
// Not in a function / not relevant
|
||||
if (!$scopeStart) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if ($scopeStart) {
|
||||
$scopeCounter += \substr_count($line, '{');
|
||||
$scopeCounter -= \substr_count($line, '}');
|
||||
|
||||
if ($scopeCounter === 0) {
|
||||
$scopeStart = false;
|
||||
}
|
||||
}
|
||||
|
||||
$lines .= $line;
|
||||
}
|
||||
|
||||
return $lines;
|
||||
};
|
||||
|
||||
foreach ($globs as $glob) {
|
||||
$files = \glob($glob);
|
||||
|
||||
foreach ($files as $file) {
|
||||
if (\stripos($file, 'Test.php')) {
|
||||
continue;
|
||||
}
|
||||
|
||||
$response = GptHelper::handleFile($file, 'php://memory', $behaviour, $fileReader);
|
||||
echo $response , \PHP_EOL , \PHP_EOL;
|
||||
}
|
||||
}
|
||||
|
||||
// complete and improve test
|
||||
$globs = [
|
||||
__DIR__ . '/../../phpOMS/*.php',
|
||||
__DIR__ . '/../../Modules/*/Models/*.php',
|
||||
];
|
||||
|
||||
$behaviour = <<<BEHAVIOUR
|
||||
Improve the given php unit test for the given function.
|
||||
BEHAVIOUR;
|
||||
|
||||
$fileReader = function ($in, $filename)
|
||||
{
|
||||
$lines = '';
|
||||
$scopeStart = false;
|
||||
$scopeCounter = 0;
|
||||
|
||||
while (($line = \fgets($in)) !== false && ($line !== '' || $scopeCounter > 0)) {
|
||||
if (\stripos($line, 'public function ') !== false || \stripos($line, 'public static function ') !== false) {
|
||||
// Check if a test exists for this function
|
||||
$testFile = \str_replace('.php', 'Test.php', $filename);
|
||||
$testFile = \str_replace('/phpOMS/', '/phpOMS/tests/', $filename);
|
||||
|
||||
if (\stripos($testFile, '../Modules/') !== false) {
|
||||
$subdirectory = "tests/";
|
||||
|
||||
$position = strrpos($testFile, "/../");
|
||||
|
||||
if ($position !== false) {
|
||||
$position = \stripos($testFile, '/', $position + 4) + 1;
|
||||
$position = \stripos($testFile, '/', $position) + 1;
|
||||
$testFile = \substr_replace($testFile, $subdirectory, $position, 0);
|
||||
}
|
||||
}
|
||||
|
||||
if (\file_exists($testFile)) {
|
||||
$scopeStart = true;
|
||||
|
||||
$testContent = \file_get_contents($testFile);
|
||||
|
||||
// Parse functio name
|
||||
$pattern = '/\bfunction\b\s+(\w+)\s*\(/';
|
||||
\preg_match($pattern, $line, $matches);
|
||||
|
||||
if (\stripos($testContent, $matches[1] ?? '~~~') !== false) {
|
||||
// Test already exists
|
||||
$scopeStart = false;
|
||||
}
|
||||
|
||||
$scopeStart = true;
|
||||
} else {
|
||||
$scopeStart = false;
|
||||
}
|
||||
}
|
||||
|
||||
// Not in a function / not relevant
|
||||
if (!$scopeStart) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if ($scopeStart) {
|
||||
$scopeCounter += \substr_count($line, '{');
|
||||
$scopeCounter -= \substr_count($line, '}');
|
||||
|
||||
if ($scopeCounter === 0) {
|
||||
$scopeStart = false;
|
||||
}
|
||||
}
|
||||
|
||||
$lines .= $line;
|
||||
}
|
||||
|
||||
return $lines;
|
||||
};
|
||||
|
||||
foreach ($globs as $glob) {
|
||||
$files = \glob($glob);
|
||||
|
||||
foreach ($files as $file) {
|
||||
if (\stripos($file, 'Test.php')) {
|
||||
continue;
|
||||
}
|
||||
|
||||
$response = GptHelper::handleFile($file, 'php://memory', $behaviour, $fileReader);
|
||||
echo $response , \PHP_EOL , \PHP_EOL;
|
||||
}
|
||||
}
|
||||
Loading…
Reference in New Issue
Block a user