'integer', 'ended_at' => 'datetime', ]; /** * Get the messages for this conversation. */ public function messages(): HasMany { return $this->hasMany(ChatbotMessage::class, 'conversation_id'); } /** * Get or create a conversation by session ID. */ public static function getOrCreateBySession(string $sessionId): self { return self::firstOrCreate( ['session_id' => $sessionId], ['session_id' => $sessionId] ); } /** * Check if the conversation is active. */ public function isActive(): bool { return $this->status === 'active'; } /** * Check if the conversation is ended. */ public function isEnded(): bool { return $this->status === 'ended'; } /** * Get the conversation context as an array of messages for the API. */ public function getContextForApi(int $maxMessages = 20): array { $messages = $this->messages() ->orderBy('created_at', 'asc') ->take($maxMessages) ->get(['role', 'content']); return $messages->map(fn($m) => [ 'role' => $m->role, 'content' => $m->content, ])->toArray(); } /** * Get the rating as star display text. */ public function getRatingStarsAttribute(): string { if (!$this->rating) { return '—'; } $stars = str_repeat('★', $this->rating) . str_repeat('☆', 5 - $this->rating); return $stars; } }