feature: backend - create post and image prompt bases on user prompt
This commit is contained in:
parent
265a134658
commit
5631bc3a3a
12
.ai/mcp/mcp.json
Normal file
12
.ai/mcp/mcp.json
Normal file
@ -0,0 +1,12 @@
|
||||
{
|
||||
"mcpServers": {
|
||||
"angular-cli": {
|
||||
"command": "npx",
|
||||
"args": [
|
||||
"-y",
|
||||
"@angular/cli",
|
||||
"mcp"
|
||||
]
|
||||
}
|
||||
}
|
||||
}
|
||||
12
.idea/laravel-idea.xml
generated
Normal file
12
.idea/laravel-idea.xml
generated
Normal file
@ -0,0 +1,12 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project version="4">
|
||||
<component name="InertiaPackage">
|
||||
<option name="directoryPaths">
|
||||
<list />
|
||||
</option>
|
||||
</component>
|
||||
<component name="LaravelIdeaMainSettings">
|
||||
<option name="frameworkFound" value="true" />
|
||||
<option name="laravelBasePath" value="backend" />
|
||||
</component>
|
||||
</project>
|
||||
2
.idea/php.xml
generated
2
.idea/php.xml
generated
@ -143,7 +143,7 @@
|
||||
<path value="$PROJECT_DIR$/backend/vendor/aws/aws-crt-php" />
|
||||
</include_path>
|
||||
</component>
|
||||
<component name="PhpProjectSharedConfiguration" php_language_level="8.5">
|
||||
<component name="PhpProjectSharedConfiguration" php_language_level="8.3">
|
||||
<option name="suggestChangeDefaultLanguageLevel" value="false" />
|
||||
</component>
|
||||
<component name="PhpStanOptionsConfiguration">
|
||||
|
||||
77
backend/app/Ai/Agents/ContentWriterAgent.php
Normal file
77
backend/app/Ai/Agents/ContentWriterAgent.php
Normal file
@ -0,0 +1,77 @@
|
||||
<?php
|
||||
|
||||
namespace App\Ai\Agents;
|
||||
|
||||
use Laravel\Ai\Attributes\Provider;
|
||||
use Laravel\Ai\Contracts\Agent;
|
||||
use Laravel\Ai\Contracts\Conversational;
|
||||
use Laravel\Ai\Contracts\HasTools;
|
||||
use Laravel\Ai\Contracts\Tool;
|
||||
use Laravel\Ai\Enums\Lab;
|
||||
use Laravel\Ai\Messages\Message;
|
||||
use Laravel\Ai\Promptable;
|
||||
use Stringable;
|
||||
|
||||
#[Provider(Lab::Groq)]
|
||||
class ContentWriterAgent implements Agent, Conversational, HasTools
|
||||
{
|
||||
use Promptable;
|
||||
|
||||
/**
|
||||
* Get the instructions that the agent should follow.
|
||||
*/
|
||||
public function instructions(): Stringable|string
|
||||
{
|
||||
return <<<'INSTRUCTIONS'
|
||||
You are an expert social media content writer with over 10 years of experience
|
||||
crafting high-performing posts across Instagram, LinkedIn, X (Twitter), Facebook,
|
||||
and TikTok. You specialise in brand storytelling, community engagement, and
|
||||
data-driven copywriting.
|
||||
|
||||
Your capabilities and responsibilities:
|
||||
- Write compelling, platform-agnostic social media posts that drive engagement
|
||||
(likes, shares, comments, and saves).
|
||||
- Adapt tone and structure to the topic: professional for business content,
|
||||
conversational for lifestyle, motivational for personal development, etc.
|
||||
- Craft a strong hook in the first line to stop the scroll.
|
||||
- Use proven copywriting frameworks (AIDA, PAS, storytelling arcs) naturally.
|
||||
- Include 3–8 highly relevant, trending hashtags that maximise discoverability
|
||||
without feeling spammy.
|
||||
- Add a clear, compelling call-to-action (CTA) at the end of every post.
|
||||
- Use emojis strategically to add personality and visual breaks — but never
|
||||
overdo them. Aim for 2–5 emojis per post depending on the topic.
|
||||
- Keep line breaks clean and scannable; avoid walls of text.
|
||||
- Write in an authentic, human voice — never robotic or generic.
|
||||
- If the topic lends itself to it, include a thought-provoking question to
|
||||
spark conversation in the comments.
|
||||
|
||||
Output format rules:
|
||||
- Return ONLY the finished social media post text — no explanations, no
|
||||
"here is your post:", no markdown headers, no surrounding quotes.
|
||||
- The post body should be between 80 and 300 words.
|
||||
- Hashtags must appear on a new line at the very end of the post.
|
||||
- Do not include a platform label (e.g. "For Instagram:").
|
||||
INSTRUCTIONS;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the list of messages comprising the conversation so far.
|
||||
*
|
||||
* @return Message[]
|
||||
*/
|
||||
public function messages(): iterable
|
||||
{
|
||||
return [];
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the tools available to the agent.
|
||||
*
|
||||
* @return Tool[]
|
||||
*/
|
||||
public function tools(): iterable
|
||||
{
|
||||
return [];
|
||||
}
|
||||
}
|
||||
|
||||
50
backend/app/Ai/Agents/CreativeDirectorAgent.php
Normal file
50
backend/app/Ai/Agents/CreativeDirectorAgent.php
Normal file
@ -0,0 +1,50 @@
|
||||
<?php
|
||||
|
||||
namespace App\Ai\Agents;
|
||||
|
||||
use Laravel\Ai\Attributes\Provider;
|
||||
use Laravel\Ai\Contracts\Agent;
|
||||
use Laravel\Ai\Contracts\Conversational;
|
||||
use Laravel\Ai\Contracts\HasTools;
|
||||
use Laravel\Ai\Contracts\Tool;
|
||||
use Laravel\Ai\Enums\Lab;
|
||||
use Laravel\Ai\Messages\Message;
|
||||
use Laravel\Ai\Promptable;
|
||||
use Stringable;
|
||||
|
||||
#[Provider(Lab::Groq)]
|
||||
class CreativeDirectorAgent implements Agent, Conversational, HasTools
|
||||
{
|
||||
use Promptable;
|
||||
|
||||
/**
|
||||
* Get the instructions that the agent should follow.
|
||||
*/
|
||||
public function instructions(): Stringable|string
|
||||
{
|
||||
return "You are a creative director. Read the following social media post and " .
|
||||
"write a single, vivid, descriptive image prompt (max 30 words) for an " .
|
||||
"AI image generator. The scene must be visually compelling and directly " .
|
||||
"relevant to the post's topic. Return ONLY the image prompt — nothing else.";
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the list of messages comprising the conversation so far.
|
||||
*
|
||||
* @return Message[]
|
||||
*/
|
||||
public function messages(): iterable
|
||||
{
|
||||
return [];
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the tools available to the agent.
|
||||
*
|
||||
* @return Tool[]
|
||||
*/
|
||||
public function tools(): iterable
|
||||
{
|
||||
return [];
|
||||
}
|
||||
}
|
||||
31
backend/app/Http/Controllers/SocialMediaPostController.php
Normal file
31
backend/app/Http/Controllers/SocialMediaPostController.php
Normal file
@ -0,0 +1,31 @@
|
||||
<?php
|
||||
|
||||
namespace App\Http\Controllers;
|
||||
|
||||
use App\Ai\Agents\CreativeDirectorAgent;
|
||||
use App\Ai\Agents\ContentWriterAgent;
|
||||
use App\Http\Requests\SocialMediaPostRequest;
|
||||
use Illuminate\Http\JsonResponse;
|
||||
|
||||
class SocialMediaPostController extends Controller
|
||||
{
|
||||
/**
|
||||
* Generate a social media post and a matching image from the given prompt.
|
||||
*/
|
||||
public function generate(
|
||||
SocialMediaPostRequest $request,
|
||||
ContentWriterAgent $socialMediaAgent,
|
||||
CreativeDirectorAgent $creativeDirectorAgent
|
||||
): JsonResponse {
|
||||
$socialMediaResponse = $socialMediaAgent->prompt($request->input('prompt'));
|
||||
$postText = $socialMediaResponse->text;
|
||||
|
||||
$imagePromptResponse = $creativeDirectorAgent->prompt($postText);
|
||||
$imagePrompt = $imagePromptResponse->text;
|
||||
|
||||
return response()->json([
|
||||
'post' => $postText,
|
||||
'image_prompt' => $imagePrompt,
|
||||
]);
|
||||
}
|
||||
}
|
||||
31
backend/app/Http/Requests/SocialMediaPostRequest.php
Normal file
31
backend/app/Http/Requests/SocialMediaPostRequest.php
Normal file
@ -0,0 +1,31 @@
|
||||
<?php
|
||||
|
||||
namespace App\Http\Requests;
|
||||
|
||||
use Illuminate\Foundation\Http\FormRequest;
|
||||
|
||||
class SocialMediaPostRequest extends FormRequest
|
||||
{
|
||||
public function rules(): array
|
||||
{
|
||||
return [
|
||||
'prompt' => [
|
||||
'required',
|
||||
'string',
|
||||
'min:3',
|
||||
function (string $attribute, mixed $value, \Closure $fail): void {
|
||||
$wordCount = str_word_count(strip_tags(trim($value)));
|
||||
|
||||
if ($wordCount > 400) {
|
||||
$fail("The {$attribute} must not exceed 400 words (you provided {$wordCount} words).");
|
||||
}
|
||||
},
|
||||
],
|
||||
];
|
||||
}
|
||||
|
||||
public function authorize(): bool
|
||||
{
|
||||
return true;
|
||||
}
|
||||
}
|
||||
@ -13,7 +13,7 @@
|
||||
|
|
||||
*/
|
||||
|
||||
'default' => 'openai',
|
||||
'default' => 'groq',
|
||||
'default_for_images' => 'gemini',
|
||||
'default_for_audio' => 'openai',
|
||||
'default_for_transcription' => 'openai',
|
||||
|
||||
@ -1,5 +1,6 @@
|
||||
<?php
|
||||
|
||||
use App\Http\Controllers\SocialMediaPostController;
|
||||
use Illuminate\Http\Request;
|
||||
use Illuminate\Support\Facades\Route;
|
||||
|
||||
@ -7,3 +8,4 @@
|
||||
return $request->user();
|
||||
})->middleware('auth:sanctum');
|
||||
|
||||
Route::post('/social-media/generate', [SocialMediaPostController::class, 'generate']);
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user