feat: ai prompt change
This commit is contained in:
parent
6ac36e3de4
commit
2d6e4db390
|
|
@ -9,6 +9,7 @@ use App\Enums\MealPostVisibility;
|
||||||
use App\Models\MealPosts;
|
use App\Models\MealPosts;
|
||||||
use App\Models\User;
|
use App\Models\User;
|
||||||
use Illuminate\Contracts\Support\Arrayable;
|
use Illuminate\Contracts\Support\Arrayable;
|
||||||
|
use Illuminate\Database\Eloquent\Relations\HasMany;
|
||||||
use Illuminate\Support\Facades\DB;
|
use Illuminate\Support\Facades\DB;
|
||||||
use Illuminate\Support\Facades\Hash;
|
use Illuminate\Support\Facades\Hash;
|
||||||
use Illuminate\Support\Str;
|
use Illuminate\Support\Str;
|
||||||
|
|
@ -86,19 +87,48 @@ class AiMealPostGenerator
|
||||||
|
|
||||||
private function mealPrompt(): string
|
private function mealPrompt(): string
|
||||||
{
|
{
|
||||||
$season = now()->locale('fr')->translatedFormat('F');
|
$recentMainIngredients = $this->recentMainIngredientsToAvoid();
|
||||||
|
$avoidRecentIngredients = $recentMainIngredients === []
|
||||||
|
? '- Aucun ingredient recent a eviter pour cette generation.'
|
||||||
|
: '- Evite les ingredients principaux deja utilises dans les 10 derniers repas: '.implode(', ', $recentMainIngredients).'.';
|
||||||
|
|
||||||
return <<<PROMPT
|
return <<<PROMPT
|
||||||
Genere un plat aleatoire pour le mois de {$season}.
|
Genere un plat completement aleatoire, sans tenir compte du mois actuel, de la saison ou des produits de saison.
|
||||||
|
|
||||||
Contraintes:
|
Contraintes:
|
||||||
- Le plat doit etre realiste, appetissant et suffisamment different des classiques trop evidents.
|
- Le plat doit etre realiste, appetissant et suffisamment different des classiques trop evidents.
|
||||||
|
- Choisis librement la cuisine, le pays, le moment de la journee et les ingredients.
|
||||||
- Retourne une seule portion avec calories, macros et ingredients coherents.
|
- Retourne une seule portion avec calories, macros et ingredients coherents.
|
||||||
- Evite les aliments impossibles a representer clairement en photo.
|
- Evite les aliments impossibles a representer clairement en photo.
|
||||||
- Auncun texte sur l'image
|
{$avoidRecentIngredients}
|
||||||
|
- Aucun texte sur l'image.
|
||||||
PROMPT;
|
PROMPT;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return string[]
|
||||||
|
*/
|
||||||
|
private function recentMainIngredientsToAvoid(): array
|
||||||
|
{
|
||||||
|
return MealPosts::query()
|
||||||
|
->with([
|
||||||
|
'ingredients' => function (HasMany $query): void {
|
||||||
|
$query->where('position', '<=', 3);
|
||||||
|
},
|
||||||
|
])
|
||||||
|
->latest('eaten_at')
|
||||||
|
->limit(10)
|
||||||
|
->get()
|
||||||
|
->flatMap(fn (MealPosts $mealPost): array => $mealPost->ingredients
|
||||||
|
->pluck('ingredient')
|
||||||
|
->all())
|
||||||
|
->map(fn (mixed $ingredient): string => $this->cleanString($ingredient, 255))
|
||||||
|
->filter()
|
||||||
|
->unique(fn (string $ingredient): string => Str::lower($ingredient))
|
||||||
|
->values()
|
||||||
|
->all();
|
||||||
|
}
|
||||||
|
|
||||||
private function imagePrompt(array $draft): string
|
private function imagePrompt(array $draft): string
|
||||||
{
|
{
|
||||||
$prompt = $this->cleanString($draft['image_prompt'] ?? '', 1500);
|
$prompt = $this->cleanString($draft['image_prompt'] ?? '', 1500);
|
||||||
|
|
|
||||||
|
|
@ -19,6 +19,33 @@ it('generates an ai meal post with an image', function () {
|
||||||
config()->set('meal_posts.ai_generation.image_path', 'meal-posts/ai-generated');
|
config()->set('meal_posts.ai_generation.image_path', 'meal-posts/ai-generated');
|
||||||
config()->set('meal_posts.ai_generation.image_quality', 'medium');
|
config()->set('meal_posts.ai_generation.image_quality', 'medium');
|
||||||
|
|
||||||
|
foreach (range(1, 11) as $index) {
|
||||||
|
$mealPost = MealPosts::factory()->create([
|
||||||
|
'eaten_at' => now()->subMinutes(11 - $index),
|
||||||
|
]);
|
||||||
|
|
||||||
|
$mealPost->ingredients()->createMany([
|
||||||
|
[
|
||||||
|
'position' => 1,
|
||||||
|
'ingredient' => $index === 1 ? 'Topinambour ancien' : "Ingredient recent {$index}",
|
||||||
|
'quantity' => 120,
|
||||||
|
'unit' => IngredientUnit::GRAM->value,
|
||||||
|
],
|
||||||
|
[
|
||||||
|
'position' => 2,
|
||||||
|
'ingredient' => $index === 11 ? 'Asperges' : "Accompagnement recent {$index}",
|
||||||
|
'quantity' => 80,
|
||||||
|
'unit' => IngredientUnit::GRAM->value,
|
||||||
|
],
|
||||||
|
[
|
||||||
|
'position' => 4,
|
||||||
|
'ingredient' => "Garniture ignoree {$index}",
|
||||||
|
'quantity' => 10,
|
||||||
|
'unit' => IngredientUnit::GRAM->value,
|
||||||
|
],
|
||||||
|
]);
|
||||||
|
}
|
||||||
|
|
||||||
MealMaker::fake([
|
MealMaker::fake([
|
||||||
[
|
[
|
||||||
'title' => 'Bowl de saumon croustillant',
|
'title' => 'Bowl de saumon croustillant',
|
||||||
|
|
@ -53,7 +80,10 @@ it('generates an ai meal post with an image', function () {
|
||||||
$this->artisan('meal-posts:generate-ai')
|
$this->artisan('meal-posts:generate-ai')
|
||||||
->assertExitCode(0);
|
->assertExitCode(0);
|
||||||
|
|
||||||
$mealPost = MealPosts::query()->with('user', 'ingredients')->firstOrFail();
|
$mealPost = MealPosts::query()
|
||||||
|
->where('ai_generated', true)
|
||||||
|
->with('user', 'ingredients')
|
||||||
|
->firstOrFail();
|
||||||
|
|
||||||
expect($mealPost->ai_generated)->toBeTrue()
|
expect($mealPost->ai_generated)->toBeTrue()
|
||||||
->and($mealPost->title)->toBe('Bowl de saumon croustillant')
|
->and($mealPost->title)->toBe('Bowl de saumon croustillant')
|
||||||
|
|
@ -75,7 +105,13 @@ it('generates an ai meal post with an image', function () {
|
||||||
]);
|
]);
|
||||||
|
|
||||||
MealMaker::assertPrompted(
|
MealMaker::assertPrompted(
|
||||||
fn ($prompt): bool => str_contains($prompt->prompt, 'Genere un plat aleatoire')
|
fn ($prompt): bool => str_contains($prompt->prompt, 'Genere un plat completement aleatoire')
|
||||||
|
&& str_contains($prompt->prompt, 'sans tenir compte du mois actuel')
|
||||||
|
&& str_contains($prompt->prompt, 'Evite les ingredients principaux deja utilises dans les 10 derniers repas')
|
||||||
|
&& str_contains($prompt->prompt, 'Ingredient recent 2')
|
||||||
|
&& str_contains($prompt->prompt, 'Asperges')
|
||||||
|
&& ! str_contains($prompt->prompt, 'Topinambour ancien')
|
||||||
|
&& ! str_contains($prompt->prompt, 'Garniture ignoree 11')
|
||||||
);
|
);
|
||||||
|
|
||||||
Image::assertGenerated(
|
Image::assertGenerated(
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue