Skip to content
Draft
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
1 change: 1 addition & 0 deletions composer.json
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@
"prefer-stable": true,
"require": {
"php": "^8.1",
"google-gemini-php/client": "^1.0",
"httpsoft/http-basis": "^1.1",
"phpspec/php-diff": "^1.1.3",
"psr/http-message": "^1.0|^2.0",
Expand Down
4 changes: 4 additions & 0 deletions config/params.php
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,10 @@
'class' => Generators\ActiveRecord\Generator::class,
'parameters' => [],
],
[
'class' => Generators\Gemini\Generator::class,
'parameters' => [],
],
],
'parameters' => [
'templates' => [],
Expand Down
60 changes: 60 additions & 0 deletions src/Generator/Gemini/Command.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
<?php

declare(strict_types=1);

namespace Yiisoft\Yii\Gii\Generator\Gemini;

use Yiisoft\Validator\Rule\Required;
use Yiisoft\Yii\Gii\Generator\AbstractGeneratorCommand;
use Yiisoft\Yii\Gii\Validator\TemplateRule;

final class Command extends AbstractGeneratorCommand
{
public function __construct(
#[Required]
private readonly string $prompt = 'Hello',
#[Required]
private readonly string $resultFilePath = 'src/gemini.txt',
#[Required(message: 'A code template must be selected.')]
#[TemplateRule]
protected string $template = 'default',
) {
parent::__construct($template);
}

public function getResultFilePath(): string
{
return $this->resultFilePath;
}

public function getPrompt(): string
{
return $this->prompt;
}

public static function getAttributeLabels(): array
{
return [
'resultFilePath' => 'Model namespace',
'prompt' => 'Text prompt',
'template' => 'Template',
];
}

public static function getHints(): array
{
return [
'resultFilePath' => 'Namespace for the model class to store it in the related directory.',
'prompt' => 'Text to ask.',
];
}

public static function getAttributes(): array
{
return [
'prompt',
'resultFilePath',
'template',
];
}
}
110 changes: 110 additions & 0 deletions src/Generator/Gemini/Generator.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,110 @@
<?php

declare(strict_types=1);

namespace Yiisoft\Yii\Gii\Generator\Gemini;

use Gemini;
use InvalidArgumentException;
use Yiisoft\Aliases\Aliases;
use Yiisoft\Validator\ValidatorInterface;
use Yiisoft\Yii\Gii\Component\CodeFile\CodeFile;
use Yiisoft\Yii\Gii\Generator\AbstractGenerator;
use Yiisoft\Yii\Gii\GeneratorCommandInterface;
use Yiisoft\Yii\Gii\ParametersProvider;

/**
* This generator will generate a controller and one or a few action view files.
*/
final class Generator extends AbstractGenerator
{
public function __construct(
Aliases $aliases,
ValidatorInterface $validator,
ParametersProvider $parametersProvider,
) {
parent::__construct($aliases, $validator, $parametersProvider);
}

public static function getId(): string
{
return 'ai-gemini';
}

public static function getName(): string
{
return 'AI / Gemini';
}

public static function getDescription(): string
{
return '';
}

public function getRequiredTemplates(): array
{
return [
'model.php',
];
}

public function doGenerate(GeneratorCommandInterface $command): array
{
if (!$command instanceof Command) {
throw new InvalidArgumentException();
}

$apiKey = getenv('GEMINI_API_KEY');
$client = Gemini::client($apiKey);

Check failure on line 58 in src/Generator/Gemini/Generator.php

View workflow job for this annotation

GitHub Actions / psalm / PHP 8.3-ubuntu-latest

src/Generator/Gemini/Generator.php:58:34: PossiblyFalseArgument: Argument 1 of Gemini::client cannot be false, possibly string value expected (see https://psalm.dev/104)

Check failure on line 58 in src/Generator/Gemini/Generator.php

View workflow job for this annotation

GitHub Actions / psalm / PHP 8.3-ubuntu-latest

src/Generator/Gemini/Generator.php:58:34: PossiblyFalseArgument: Argument 1 of Gemini::client cannot be false, possibly string value expected (see https://psalm.dev/104)

//$prompt = $command->getPrompt();
$prompt = [
'Generate a test with PHPUnit for the following class',
file_get_contents(__DIR__ . '/../../Gii.php'),
];
$result = $client->geminiPro()->generateContent($prompt);

Check failure on line 65 in src/Generator/Gemini/Generator.php

View workflow job for this annotation

GitHub Actions / psalm / PHP 8.3-ubuntu-latest

src/Generator/Gemini/Generator.php:65:57: InvalidArgument: Argument 1 of Gemini\Resources\GenerativeModel::generateContent expects Gemini\Data\Blob|Gemini\Data\Content|array<array-key, Gemini\Data\Blob|string>|string, but list{'Generate a test with PHPUnit for the following class', false|string} provided (see https://psalm.dev/004)

Check failure on line 65 in src/Generator/Gemini/Generator.php

View workflow job for this annotation

GitHub Actions / psalm / PHP 8.3-ubuntu-latest

src/Generator/Gemini/Generator.php:65:57: InvalidArgument: Argument 1 of Gemini\Resources\GenerativeModel::generateContent expects Gemini\Data\Blob|Gemini\Data\Content|array<array-key, Gemini\Data\Blob|string>|string, but list{'Generate a test with PHPUnit for the following class', false|string} provided (see https://psalm.dev/004)

$rootPath = $this->aliases->get('@root');

$path = $this->getOutputFile($command);
$fileContent = preg_replace(
'/^(```[a-z]+)\r?\n?|\r?\n?```$/i',
'',
$result->text(),
);
$codeFile = (new CodeFile(
$path,
$fileContent,

Check failure on line 77 in src/Generator/Gemini/Generator.php

View workflow job for this annotation

GitHub Actions / psalm / PHP 8.3-ubuntu-latest

src/Generator/Gemini/Generator.php:77:13: PossiblyNullArgument: Argument 2 of Yiisoft\Yii\Gii\Component\CodeFile\CodeFile::__construct cannot be null, possibly null value provided (see https://psalm.dev/078)

Check failure on line 77 in src/Generator/Gemini/Generator.php

View workflow job for this annotation

GitHub Actions / psalm / PHP 8.3-ubuntu-latest

src/Generator/Gemini/Generator.php:77:13: PossiblyNullArgument: Argument 2 of Yiisoft\Yii\Gii\Component\CodeFile\CodeFile::__construct cannot be null, possibly null value provided (see https://psalm.dev/078)
))->withBasePath($rootPath);

$files = [];
$files[$codeFile->getId()] = $codeFile;

return $files;
}

/**
* @return string the controller class file path
*/
private function getOutputFile(Command $command): string
{
$directory = '@root/';

return $this->aliases->get(
str_replace(
['\\', '//'],
'/',
sprintf(
'%s/%s',
$directory,
$command->getResultFilePath(),
),
),
);
}

public static function getCommandClass(): string
{
return Command::class;
}
}
Loading