This commit is contained in:
ct
2025-06-21 09:13:23 +08:00
parent db10fc3f1c
commit 8e58f85860
39 changed files with 684 additions and 181 deletions

View File

@@ -53,7 +53,7 @@ public static function getVectorEmbeddingBgeSmall($embedding_query)
KeywordEmbedding::create([
'keyword' => $embedding_query,
'embedding' => $embedding
'embedding' => $embedding,
]);
break;

View File

@@ -12,7 +12,7 @@ public static function getMemeKeywords(string $name, string $description)
$response = Http::withHeaders([
'Content-Type' => 'application/json',
'Authorization' => 'Bearer ' . $apiKey,
'Authorization' => 'Bearer '.$apiKey,
])->post('https://api.openai.com/v1/responses', [
'model' => 'gpt-4.1-nano',
'input' => [
@@ -64,7 +64,7 @@ public static function getSingleMemeGenerator($user_prompt)
$response = Http::withHeaders([
'Content-Type' => 'application/json',
'Authorization' => 'Bearer ' . env('OPENAI_API_KEY'),
'Authorization' => 'Bearer '.env('OPENAI_API_KEY'),
])
->post('https://api.openai.com/v1/responses', [
'model' => 'gpt-4.1-nano',
@@ -102,7 +102,7 @@ public static function getSingleMemeGenerator($user_prompt)
],
'primary_keyword_type' => [
'type' => 'string',
'description' => "Primary keyword type, choose only between: (action|emotion|misc)",
'description' => 'Primary keyword type, choose only between: (action|emotion|misc)',
],
'action_keywords' => [
'type' => 'array',
@@ -168,7 +168,7 @@ public static function getSingleMemeGenerator($user_prompt)
return $data;
} else {
// Handle error
throw new \Exception('API request failed: ' . $response->body());
throw new \Exception('API request failed: '.$response->body());
}
}

View File

@@ -8,8 +8,6 @@
use App\Models\MemeMedia;
use App\Models\MemeMediaEmbedding;
use Exception;
use Illuminate\Contracts\Filesystem\Cloud;
use PhpParser\Lexer\TokenEmulator\KeywordEmulator;
class KeywordEmbeddingMaintenance
{
@@ -24,7 +22,7 @@ public static function populateCategoryEmbeddings()
foreach ($categories as $category) {
$embedding_query = $category->name . " " . $category->description;
$embedding_query = $category->name.' '.$category->description;
$keyword_embedding = KeywordEmbedding::where('keyword', $embedding_query)->first();
@@ -75,7 +73,6 @@ public static function populateMemeMediasKeywordsEmbeddings()
dump("{Processing: {$count}/{$max}: {$meme_media->name}");
// keywords:
foreach ($meme_media->keywords as $keyword) {
@@ -113,7 +110,6 @@ public static function populateMemeMediasKeywordsEmbeddings()
dump("Populating emotion keyword embedding for {$keyword}");
$embedding = self::fetchAndCacheEmbedding($keyword);
if ($embedding) {
MemeMediaEmbedding::create([
'meme_media_id' => $meme_media->id,
@@ -140,8 +136,8 @@ public static function populateMemeMediasKeywordsEmbeddings()
}
dump("✓ Successfully processed meme media {$meme_media->id}");
dump("");
dump("");
dump('');
dump('');
}
}
@@ -150,7 +146,7 @@ public static function populateMemeMediaEmbeddings()
$meme_medias = MemeMedia::whereNotNull('embedding')->get();
foreach ($meme_medias as $meme_media) {
$embedding_query = $meme_media->name . " " . $meme_media->description;
$embedding_query = $meme_media->name.' '.$meme_media->description;
$keyword_embedding = KeywordEmbedding::where('keyword', $embedding_query)->first();
@@ -170,7 +166,6 @@ private static function fetchAndCacheEmbedding($keyword)
$max_retries = 3;
$current_attempt = 0;
while ($embedding === null && $current_attempt < $max_retries) {
$current_attempt++;
try {

View File

@@ -15,11 +15,11 @@ public static function generateMemesByCategories()
Category::where('system_memes_generated_count', '<', 1)
->chunk(10, function ($categories) {
foreach ($categories as $category) {
dump('Processing ' . $category->name);
dump('Processing '.$category->name);
$meme = MemeGenerator::generateMemeByCategory($category);
if (!is_null($meme)) {
if (! is_null($meme)) {
$category->system_memes_generated_count++;
$category->save();
}
@@ -27,15 +27,13 @@ public static function generateMemesByCategories()
});
}
public static function patchMemeKeywords()
{
$meme_medias = MemeMedia::whereNull('action_keywords')->get();
foreach ($meme_medias as $key => $meme_media) {
dump('Processing ' . $key + 1 . '/' . $meme_medias->count() . ': ' . $meme_media->name);
dump('Processing '.$key + 1 .'/'.$meme_medias->count().': '.$meme_media->name);
$meme_keywords_response = OpenAI::getMemeKeywords($meme_media->name, $meme_media->description);

View File

@@ -27,7 +27,6 @@ public static function getSuitableMemeMedia(Meme $meme, $tolerance = 5)
{
$meme_media = null;
$primary_keyword_type = $meme->primary_keyword_type;
if ($primary_keyword_type == 'action') {
@@ -40,7 +39,7 @@ public static function getSuitableMemeMedia(Meme $meme, $tolerance = 5)
$meme_media = self::getMemeMediaByKeywords($keywords, $tolerance);
}
} else if ($primary_keyword_type == 'emotion') {
} elseif ($primary_keyword_type == 'emotion') {
$meme_media = self::getMemeMediaByKeywords($meme->emotion_keywords, $tolerance, 'emotion_keywords');
if (is_null($meme_media)) {
@@ -48,8 +47,8 @@ public static function getSuitableMemeMedia(Meme $meme, $tolerance = 5)
$meme_media = self::getMemeMediaByKeywords($keywords, $tolerance);
}
} else if ($primary_keyword_type == 'misc') {
$meme_media = self::getMemeMediaByKeywords($meme->misc_keywords, $tolerance, 'misc_keywords');
} elseif ($primary_keyword_type == 'misc') {
$meme_media = self::getMemeMediaByKeywords($meme->misc_keywords, $tolerance, 'misc_keywords');
if (is_null($meme_media)) {
$keywords = array_merge($meme->action_keywords, $meme->emotion_keywords, $meme->keywords);
@@ -97,7 +96,7 @@ public static function generateMemeByCategory(Category $category)
$meme->background_media_id = self::generateBackgroundMediaWithRunware($meme_output->background)->id;
if (
//!is_null($meme->meme_media_id) &&
// !is_null($meme->meme_media_id) &&
! is_null($meme->background_media_id)
) {
$meme->status = self::STATUS_COMPLETED;
@@ -117,13 +116,13 @@ public static function generateMemeOutputByCategory(Category $category)
$random_keyword = Str::lower($category->name);
if (! is_null($category->parent_id)) {
$random_keyword = $category->parent->name . ' - ' . $random_keyword;
$random_keyword = $category->parent->name.' - '.$random_keyword;
}
if (! is_null($category->meme_angles)) {
$random_keyword .= ' - ' . collect($category->meme_angles)->random();
$random_keyword .= ' - '.collect($category->meme_angles)->random();
} elseif (! is_null($category->keywords)) {
$random_keyword .= ' - ' . collect($category->keywords)->random();
$random_keyword .= ' - '.collect($category->keywords)->random();
}
$prompt = "Write me 1 meme about {$random_keyword}";
@@ -170,7 +169,7 @@ public static function generateMemeOutputByCategory(Category $category)
$meme_output = (object) [
'success' => false,
'attempts' => $attempt, // Optional: track how many attempts were made
'error' => 'Failed to generate valid meme after ' . $retries . ' attempts',
'error' => 'Failed to generate valid meme after '.$retries.' attempts',
];
}
@@ -214,16 +213,14 @@ public static function getMemeMediaByKeywords(array $keywords, int $tolerance =
$meme_embedding = CloudflareAI::getVectorEmbeddingBgeSmall(implode(' ', $keywords));
$meme_medias = MemeMediaEmbedding::query()
->when(!is_empty($tag), function ($query) use ($tag) {
->when(! is_empty($tag), function ($query) use ($tag) {
return $query->where('tag', $tag);
})
->nearestNeighbors('embedding', $meme_embedding, Distance::L2)
->take($tolerance)
->get();
if ($meme_medias->count() > 0) {
$meme_media = $meme_medias->random()->meme_media;
}

View File

@@ -19,8 +19,6 @@
* @property string|null $tag
* @property Carbon|null $created_at
* @property Carbon|null $updated_at
*
* @package App\Models
*/
class KeywordEmbedding extends Model
{
@@ -33,6 +31,6 @@ class KeywordEmbedding extends Model
protected $fillable = [
'keyword',
'embedding',
'tag'
'tag',
];
}

View File

@@ -21,10 +21,7 @@
* @property string|null $tag
* @property Carbon|null $created_at
* @property Carbon|null $updated_at
*
* @property MemeMedia $meme_media
*
* @package App\Models
*/
class MemeMediaEmbedding extends Model
{
@@ -41,7 +38,7 @@ class MemeMediaEmbedding extends Model
'meme_media_id',
'keyword',
'embedding',
'tag'
'tag',
];
public function meme_media()