diff --git a/app/Http/Controllers/ChatController.php b/app/Http/Controllers/ChatController.php index e080788..5bd9ae2 100644 --- a/app/Http/Controllers/ChatController.php +++ b/app/Http/Controllers/ChatController.php @@ -116,32 +116,30 @@ public function stream(Request $request, ?Chat $chat = null) } return response()->stream(function () use ($request, $chat) { - $messages = $request->input('messages', []); + $messages = collect($request->input('messages', [])); + $prompt = $request->string('prompt')->trim()->value(); + $autoStream = $request->input('autoStream', false); - if (empty($messages)) { + if ($messages->isEmpty() && empty($prompt) && ! $autoStream) { return; } - // Only save messages if we have an existing chat (authenticated user with saved chat) - if ($chat) { - foreach ($messages as $message) { - // Only save if message doesn't have an ID (not from database) - if (! isset($message['id'])) { - $chat->messages()->create([ - 'type' => $message['type'], - 'content' => $message['content'], - ]); - } + // Only save/load messages if we have an existing chat (authenticated user with saved chat) + if ($chat && Auth::check()) { + if ($prompt && ! $autoStream) { + $chat->messages()->create([ + 'type' => 'prompt', + 'content' => $prompt, + ]); } + $messages = $chat->messages()->orderBy('created_at')->get(); } // Prepare messages for OpenAI - $openAIMessages = collect($messages) - ->map(fn ($message) => [ - 'role' => $message['type'] === 'prompt' ? 'user' : 'assistant', - 'content' => $message['content'], - ]) - ->toArray(); + $openAIMessages = $messages->map(fn ($message) => [ + 'role' => $message['type'] === 'prompt' ? 'user' : 'assistant', + 'content' => $message['content'], + ])->toArray(); // Stream response from OpenAI $fullResponse = ''; diff --git a/resources/js/pages/chat.tsx b/resources/js/pages/chat.tsx index 926d226..05a7dcc 100644 --- a/resources/js/pages/chat.tsx +++ b/resources/js/pages/chat.tsx @@ -61,7 +61,10 @@ function ChatWithStream({ chat, auth, flash }: { chat: ChatType | undefined; aut if (shouldAutoStream) { setTimeout(() => { - send({ messages: chat.messages }); + const first = chat.messages[0]; + if (first.type === 'prompt') { + send({ autoStream: 1 }); + } }, 100); } }, [chat?.messages, flash?.stream, send]); // Only run on mount @@ -126,8 +129,12 @@ function ChatWithStream({ chat, auth, flash }: { chat: ChatType | undefined; aut // Update local state setMessages((prev) => [...prev, ...toAdd]); - // Send all messages including the new ones - send({ messages: [...messages, ...toAdd] }); + // Send message data based on chat/auth status + if (chat && auth.user) { + send({ prompt: query }); + } else { + send({ messages: [...messages, ...toAdd] }); + } input.value = ''; inputRef.current?.focus(); diff --git a/tests/Feature/ChatFlowTest.php b/tests/Feature/ChatFlowTest.php index d0d12b8..1589a77 100644 --- a/tests/Feature/ChatFlowTest.php +++ b/tests/Feature/ChatFlowTest.php @@ -64,9 +64,7 @@ public function test_message_from_home_page_creates_chat_and_sends_message(): vo // Now send the message to the new chat $response = $this->post("/chat/{$chat->id}/stream", [ - 'messages' => [ - ['type' => 'prompt', 'content' => 'Hello from home page'], - ], + 'prompt' => 'Hello from home page', ]); $response->assertStatus(200); diff --git a/tests/Feature/ChatStreamingTest.php b/tests/Feature/ChatStreamingTest.php index 041efcb..07e184c 100644 --- a/tests/Feature/ChatStreamingTest.php +++ b/tests/Feature/ChatStreamingTest.php @@ -34,9 +34,7 @@ public function test_authenticated_user_streams_to_existing_chat(): void $chat = Chat::factory()->create(['user_id' => $user->id]); $response = $this->actingAs($user)->post("/chat/{$chat->id}/stream", [ - 'messages' => [ - ['type' => 'prompt', 'content' => 'Hello AI'], - ], + 'prompt' => 'Hello AI', ]); $response->assertStatus(200); @@ -69,43 +67,6 @@ public function test_empty_messages_returns_early(): void $this->assertDatabaseCount('messages', 0); } - public function test_messages_marked_as_saved_are_not_duplicated(): void - { - $user = User::factory()->create(); - $chat = Chat::factory()->create(['user_id' => $user->id]); - - // Create existing message - $existingMessage = Message::factory()->create([ - 'chat_id' => $chat->id, - 'type' => 'prompt', - 'content' => 'Already saved', - ]); - - $response = $this->actingAs($user)->post("/chat/{$chat->id}/stream", [ - 'messages' => [ - ['id' => $existingMessage->id, 'type' => 'prompt', 'content' => 'Already saved'], - ['type' => 'prompt', 'content' => 'New message'], - ], - ]); - - $response->assertStatus(200); - - // Get the streaming content - $response->streamedContent(); - - // Verify only the new message was saved (1 existing + 1 new prompt + 1 AI response) - $this->assertDatabaseCount('messages', 3); - $this->assertDatabaseHas('messages', [ - 'chat_id' => $chat->id, - 'content' => 'New message', - ]); - $this->assertDatabaseHas('messages', [ - 'chat_id' => $chat->id, - 'type' => 'response', - 'content' => 'This is a test response.', - ]); - } - public function test_chat_not_created_for_anonymous_users(): void { $response = $this->post('/chat/stream', [