*/ public function index(): array { $userId = auth()->id(); $user = auth()->user(); $query = PromptProject::with(['user', 'provider', 'model']) ->latest(); if (!$user || $user->role !== 'superadmin') { $query->where('user_id', $userId); } $paginator = $query->paginate(15); return [ 'data' => $paginator->items(), 'total' => $paginator->total(), 'per_page' => $paginator->perPage(), 'current_page' => $paginator->currentPage(), 'last_page' => $paginator->lastPage(), 'from' => $paginator->firstItem(), 'to' => $paginator->lastItem(), ]; } /** * Store a newly created resource in storage. */ public function store(array $data): PromptProject { $data['examples'] = $this->convertToArray($data['examples'] ?? null); $data['variables'] = $this->convertToArray($data['variables'] ?? null); return PromptProject::create($data); } /** * Update the specified resource in storage. */ public function update(PromptProject $project, array $data): PromptProject { $data['examples'] = $this->convertToArray($data['examples'] ?? null); $data['variables'] = $this->convertToArray($data['variables'] ?? null); $project->update($data); return $project; } /** * Convert string to array. */ private function convertToArray(mixed $value): ?array { if (is_array($value)) { return $value; } if (is_string($value)) { $value = trim($value); if ($value === '') { return null; } return array_map('trim', explode(',', $value)); } return null; } /** * Remove the specified resource from storage. */ public function destroy(PromptProject $project): bool { try { $project->delete(); return true; } catch (RuntimeException $e) { Log::error('Failed to delete prompt project: ' . $e->getMessage()); return false; } } /** * Generate prompt for the specified project. */ public function generate(PromptProject $project, mixed $model = null, ?int $userId = null): PromptGeneration { $provider = $project->provider; if (!$provider instanceof AiProvider) { throw new InvalidArgumentException('AI provider is required for generation.'); } if (!$model) { $model = $project->model; } if (!$model) { throw new InvalidArgumentException('AI model is required for generation.'); } if (is_string($model)) { $model = AiModel::firstOrCreate( ['provider_id' => $provider->id, 'slug' => $model], ['name' => $model, 'slug' => $model, 'is_active' => true] ); } $modelSlug = $model->slug; $modelId = $model->id; $userId ??= auth()->id(); $promptText = $this->buildPrompt($project); $aiData = [ 'prompt' => $promptText, 'temperature' => (float) ($project->temperature ?? 0.7), 'max_tokens' => (int) ($project->max_tokens ?? 1024), 'model' => $modelSlug, 'api_key' => $provider->api_key, 'base_url' => $provider->base_url, ]; $startTime = microtime(true); try { $service = $this->aiServiceFactory->make($provider); $result = $service->generatePrompt($aiData); } catch (ConnectionException|RuntimeException $e) { Log::error('Prompt generation failed: ' . $e->getMessage()); return $this->generationModel::create([ 'project_id' => $project->id, 'user_id' => $userId, 'provider_id' => $provider->id, 'model_id' => $modelId, 'generated_prompt' => $promptText, 'input_data' => $aiData, 'output_data' => ['error' => $e->getMessage()], 'tokens_used' => null, 'generation_time' => round(microtime(true) - $startTime, 3), 'status' => 'failed', ]); } return $this->generationModel::create([ 'project_id' => $project->id, 'user_id' => $userId, 'provider_id' => $provider->id, 'model_id' => $modelId, 'generated_prompt' => $promptText, 'input_data' => $aiData, 'output_data' => $result, 'tokens_used' => $result['tokens_used'] ?? null, 'generation_time' => round(microtime(true) - $startTime, 3), 'status' => 'completed', ]); } /** * Build the prompt text from project data. */ public function buildPrompt(PromptProject $project): string { $parts = []; $parts[] = "You are an expert prompt engineering assistant. Your task is to generate a high-quality, optimized prompt based on the specifications provided below."; if ($project->company_name) { $parts[] = "Company Name: " . $project->company_name; } if ($project->company_address) { $parts[] = "Company Address: " . $project->company_address; } if ($project->company_whatsapp) { $parts[] = "Company WhatsApp: " . $project->company_whatsapp; } if ($project->company_website) { $parts[] = "Company Website: " . $project->company_website; } if ($project->company_social_media) { $parts[] = "Company Social Media: " . $project->company_social_media; } if ($project->company_business_activities) { $parts[] = "Company Business Activities: " . $project->company_business_activities; } if ($project->company_services_products) { $parts[] = "Company Services/Products: " . $project->company_services_products; } if ($project->objective) { $parts[] = "Objective: " . $project->objective; } if ($project->context) { $parts[] = "Context: " . $project->context; } if ($project->persona) { $parts[] = "Persona/Role: " . $project->persona; } if ($project->tone) { $parts[] = "Tone/Style: " . $project->tone; } if ($project->constraints) { $parts[] = "Constraints: " . $project->constraints; } if ($project->output_format) { $parts[] = "Output Format: " . $project->output_format; } if (!empty($project->examples)) { $parts[] = "Examples:\n" . json_encode($project->examples, JSON_PRETTY_PRINT); } if (!empty($project->variables)) { $parts[] = "Variables: " . json_encode($project->variables, JSON_PRETTY_PRINT); } $parts[] = "Generate the optimized prompt now. Return ONLY the prompt, without explanations, introductions, or additional text."; return implode("\n\n", $parts); } }