diff --git a/.github/workflows/ci-e2e-playwright.yml b/.github/workflows/ci-e2e-playwright.yml index 3bb98eb322cea..e17401297e66e 100644 --- a/.github/workflows/ci-e2e-playwright.yml +++ b/.github/workflows/ci-e2e-playwright.yml @@ -41,6 +41,12 @@ env: PGPASSWORD: posthog PGPORT: 5432 OIDC_RSA_PRIVATE_KEY: ${{ secrets.OIDC_RSA_PRIVATE_KEY }} + OPENAI_API_KEY: ${{ secrets.OPENAI_API_KEY }} + ANTHROPIC_API_KEY: ${{ secrets.ANTHROPIC_API_KEY }} + GEMINI_API_KEY: ${{ secrets.GEMINI_API_KEY }} + INKEEP_API_KEY: ${{ secrets.INKEEP_API_KEY }} + AZURE_INFERENCE_CREDENTIAL: ${{ secrets.AZURE_INFERENCE_CREDENTIAL }} + AZURE_INFERENCE_ENDPOINT: ${{ secrets.AZURE_INFERENCE_ENDPOINT }} concurrency: group: ${{ github.workflow }}-${{ github.head_ref || github.run_id }} @@ -329,7 +335,7 @@ jobs: - name: Start PostHog web & Celery worker run: | python manage.py run_autoreload_celery --type=worker &> /tmp/celery.log & - python manage.py runserver 8000 &> /tmp/server.log & + python -m granian --interface asgi posthog.asgi:application --host 0.0.0.0 --port 8000 --log-level debug --workers 1 &> /tmp/server.log & # Install Playwright browsers while we wait for PostHog to be ready - name: Install Playwright browsers diff --git a/ee/api/conversation.py b/ee/api/conversation.py index 4c04e11e0520e..5b29089f84a72 100644 --- a/ee/api/conversation.py +++ b/ee/api/conversation.py @@ -111,17 +111,15 @@ class ConversationViewSet(TeamAndOrgViewSetMixin, ListModelMixin, RetrieveModelM lookup_url_kwarg = "conversation" def safely_get_queryset(self, queryset): - # Only allow access to conversations created by the current user - qs = queryset.filter(user=self.request.user) - - # Allow sending messages to any conversation - if self.action == "create": - return qs - - # But retrieval must only return conversations from the assistant and with a title. - return qs.filter( - title__isnull=False, type__in=[Conversation.Type.DEEP_RESEARCH, Conversation.Type.ASSISTANT] - ).order_by("-updated_at") + # Only single retrieval of a specific conversation is allowed for other users' conversations (if ID known) + if self.action != "retrieve": + queryset = queryset.filter(user=self.request.user) + # For listing or single retrieval, conversations must be from the assistant and have a title + if self.action in ("list", "retrieve"): + queryset = queryset.filter( + title__isnull=False, type__in=[Conversation.Type.DEEP_RESEARCH, Conversation.Type.ASSISTANT] + ).order_by("-updated_at") + return queryset def get_throttles(self): if ( diff --git a/ee/api/test/test_conversation.py b/ee/api/test/test_conversation.py index 06daf42ac282f..9f0998819910d 100644 --- a/ee/api/test/test_conversation.py +++ b/ee/api/test/test_conversation.py @@ -156,7 +156,7 @@ def test_add_message_to_existing_conversation(self): self.assertEqual(str(workflow_inputs.trace_id), trace_id) self.assertEqual(workflow_inputs.message["content"], "test query") - def test_cant_access_other_users_conversation(self): + def test_cant_start_other_users_conversation(self): conversation = Conversation.objects.create(user=self.other_user, team=self.team) self.client.force_login(self.user) @@ -167,6 +167,18 @@ def test_cant_access_other_users_conversation(self): self.assertEqual(response.status_code, status.HTTP_400_BAD_REQUEST) + def test_cannot_cancel_other_users_conversation(self): + """Test that cancel action cannot use other user's conversation ID""" + conversation = Conversation.objects.create( + user=self.other_user, team=self.team, title="Other user conversation", type=Conversation.Type.ASSISTANT + ) + + response = self.client.patch( + f"/api/environments/{self.team.id}/conversations/{conversation.id}/cancel/", + ) + + self.assertEqual(response.status_code, status.HTTP_404_NOT_FOUND) + def test_cant_access_other_teams_conversation(self): conversation = Conversation.objects.create(user=self.user, team=self.other_team) @@ -313,11 +325,12 @@ def test_cancel_already_canceling_conversation(self): # should be idempotent self.assertEqual(response.status_code, status.HTTP_204_NO_CONTENT) - def test_cancel_other_users_conversation(self): + def test_cannot_cancel_other_users_conversation_in_same_project(self): conversation = Conversation.objects.create(user=self.other_user, team=self.team) response = self.client.patch( f"/api/environments/{self.team.id}/conversations/{conversation.id}/cancel/", ) + # This should fail because cancel action also filters by user self.assertEqual(response.status_code, status.HTTP_404_NOT_FOUND) def test_cancel_other_teams_conversation(self): @@ -484,50 +497,63 @@ def test_list_only_returns_assistant_conversations_with_title(self): self.assertIn("messages", results[0]) self.assertIn("status", results[0]) - def test_retrieve_conversation_without_title_returns_404(self): - conversation = Conversation.objects.create( - user=self.user, team=self.team, title=None, type=Conversation.Type.ASSISTANT + def test_list_conversations_only_returns_own_conversations(self): + """Test that listing conversations only returns the current user's conversations""" + # Create conversations for different users + own_conversation = Conversation.objects.create( + user=self.user, team=self.team, title="My conversation", type=Conversation.Type.ASSISTANT + ) + Conversation.objects.create( + user=self.other_user, team=self.team, title="Other user conversation", type=Conversation.Type.ASSISTANT ) with patch("langgraph.graph.state.CompiledStateGraph.aget_state", new_callable=AsyncMock): - response = self.client.get(f"/api/environments/{self.team.id}/conversations/{conversation.id}/") - self.assertEqual(response.status_code, status.HTTP_404_NOT_FOUND) + response = self.client.get(f"/api/environments/{self.team.id}/conversations/") + self.assertEqual(response.status_code, status.HTTP_200_OK) + + results = response.json()["results"] + self.assertEqual(len(results), 1) + self.assertEqual(results[0]["id"], str(own_conversation.id)) + self.assertEqual(results[0]["title"], "My conversation") - def test_retrieve_non_assistant_conversation_returns_404(self): + def test_retrieve_own_conversation_succeeds(self): + """Test that user can retrieve their own conversation""" conversation = Conversation.objects.create( - user=self.user, team=self.team, title="Tool call", type=Conversation.Type.TOOL_CALL + user=self.user, team=self.team, title="My conversation", type=Conversation.Type.ASSISTANT ) with patch("langgraph.graph.state.CompiledStateGraph.aget_state", new_callable=AsyncMock): response = self.client.get(f"/api/environments/{self.team.id}/conversations/{conversation.id}/") - self.assertEqual(response.status_code, status.HTTP_404_NOT_FOUND) + self.assertEqual(response.status_code, status.HTTP_200_OK) + self.assertEqual(response.json()["id"], str(conversation.id)) - def test_conversation_serializer_returns_empty_messages_on_validation_error(self): + def test_retrieve_other_users_conversation_succeeds(self): + """Test that user can retrieve another user's conversation in the same team""" conversation = Conversation.objects.create( - user=self.user, team=self.team, title="Conversation with validation error", type=Conversation.Type.ASSISTANT + user=self.other_user, team=self.team, title="Other user conversation", type=Conversation.Type.ASSISTANT ) - # Mock the get_state method to return data that will cause a validation error - with patch("langgraph.graph.state.CompiledStateGraph.aget_state", new_callable=AsyncMock) as mock_get_state: - - class MockSnapshot: - values = {"invalid_key": "invalid_value"} # Invalid structure for AssistantState - - mock_get_state.return_value = MockSnapshot() - + with patch("langgraph.graph.state.CompiledStateGraph.aget_state", new_callable=AsyncMock): response = self.client.get(f"/api/environments/{self.team.id}/conversations/{conversation.id}/") self.assertEqual(response.status_code, status.HTTP_200_OK) + self.assertEqual(response.json()["id"], str(conversation.id)) - # Should return empty messages array when validation fails - self.assertEqual(response.json()["messages"], []) + def test_retrieve_other_teams_conversation_fails(self): + """Test that user cannot retrieve conversation from another team""" + conversation = Conversation.objects.create( + user=self.user, team=self.other_team, title="Other team conversation", type=Conversation.Type.ASSISTANT + ) + + with patch("langgraph.graph.state.CompiledStateGraph.aget_state", new_callable=AsyncMock): + response = self.client.get(f"/api/environments/{self.team.id}/conversations/{conversation.id}/") + self.assertEqual(response.status_code, status.HTTP_404_NOT_FOUND) - def test_list_conversations_ordered_by_updated_at(self): - """Verify conversations are listed with most recently updated first""" + def test_conversations_ordered_by_updated_at_descending(self): + """Test that conversations are ordered by updated_at in descending order""" # Create conversations with different update times conversation1 = Conversation.objects.create( user=self.user, team=self.team, title="Older conversation", type=Conversation.Type.ASSISTANT ) - conversation2 = Conversation.objects.create( user=self.user, team=self.team, title="Newer conversation", type=Conversation.Type.ASSISTANT ) @@ -535,7 +561,6 @@ def test_list_conversations_ordered_by_updated_at(self): # Set updated_at explicitly to ensure order conversation1.updated_at = timezone.now() - datetime.timedelta(hours=1) conversation1.save() - conversation2.updated_at = timezone.now() conversation2.save() @@ -546,7 +571,7 @@ def test_list_conversations_ordered_by_updated_at(self): results = response.json()["results"] self.assertEqual(len(results), 2) - # First result should be the newer conversation + # First result should be the newer conversation (most recent first) self.assertEqual(results[0]["id"], str(conversation2.id)) self.assertEqual(results[0]["title"], "Newer conversation") diff --git a/ee/hogai/api/serializers.py b/ee/hogai/api/serializers.py index d911dbafeafc2..b68b98c45a2ee 100644 --- a/ee/hogai/api/serializers.py +++ b/ee/hogai/api/serializers.py @@ -5,6 +5,7 @@ from langgraph.graph.state import CompiledStateGraph from rest_framework import serializers +from posthog.api.shared import UserBasicSerializer from posthog.exceptions_capture import capture_exception from ee.hogai.chat_agent.graph import AssistantGraph @@ -15,7 +16,7 @@ from ee.hogai.utils.types.composed import AssistantMaxGraphState from ee.models.assistant import Conversation -_conversation_fields = ["id", "status", "title", "created_at", "updated_at", "type"] +_conversation_fields = ["id", "status", "title", "user", "created_at", "updated_at", "type"] MaxGraphType = DeepResearchAssistantGraph | AssistantGraph @@ -32,8 +33,10 @@ class Meta: fields = _conversation_fields read_only_fields = fields + user = UserBasicSerializer(read_only=True) -class ConversationSerializer(serializers.ModelSerializer): + +class ConversationSerializer(ConversationMinimalSerializer): class Meta: model = Conversation fields = [*_conversation_fields, "messages", "has_unsupported_content"] diff --git a/frontend/__snapshots__/scenes-app-max-ai--shared-thread--dark.png b/frontend/__snapshots__/scenes-app-max-ai--shared-thread--dark.png new file mode 100644 index 0000000000000..bc8c42ee1ac81 Binary files /dev/null and b/frontend/__snapshots__/scenes-app-max-ai--shared-thread--dark.png differ diff --git a/frontend/__snapshots__/scenes-app-max-ai--shared-thread--light.png b/frontend/__snapshots__/scenes-app-max-ai--shared-thread--light.png new file mode 100644 index 0000000000000..3110550bb81f7 Binary files /dev/null and b/frontend/__snapshots__/scenes-app-max-ai--shared-thread--light.png differ diff --git a/frontend/__snapshots__/scenes-app-posthog-ai--chat-with-ui-context--dark.png b/frontend/__snapshots__/scenes-app-posthog-ai--chat-with-ui-context--dark.png index b9405e2b8625e..da7d9cad100a6 100644 Binary files a/frontend/__snapshots__/scenes-app-posthog-ai--chat-with-ui-context--dark.png and b/frontend/__snapshots__/scenes-app-posthog-ai--chat-with-ui-context--dark.png differ diff --git a/frontend/__snapshots__/scenes-app-posthog-ai--chat-with-ui-context--light.png b/frontend/__snapshots__/scenes-app-posthog-ai--chat-with-ui-context--light.png index 62c4dc81aadf5..fc8031397ddb2 100644 Binary files a/frontend/__snapshots__/scenes-app-posthog-ai--chat-with-ui-context--light.png and b/frontend/__snapshots__/scenes-app-posthog-ai--chat-with-ui-context--light.png differ diff --git a/frontend/__snapshots__/scenes-app-posthog-ai--empty-thread-loading--dark.png b/frontend/__snapshots__/scenes-app-posthog-ai--empty-thread-loading--dark.png index f8169ee7882c0..812b04f9d3b9d 100644 Binary files a/frontend/__snapshots__/scenes-app-posthog-ai--empty-thread-loading--dark.png and b/frontend/__snapshots__/scenes-app-posthog-ai--empty-thread-loading--dark.png differ diff --git a/frontend/__snapshots__/scenes-app-posthog-ai--empty-thread-loading--light.png b/frontend/__snapshots__/scenes-app-posthog-ai--empty-thread-loading--light.png index 4f643693e1e44..1b898f1df3f55 100644 Binary files a/frontend/__snapshots__/scenes-app-posthog-ai--empty-thread-loading--light.png and b/frontend/__snapshots__/scenes-app-posthog-ai--empty-thread-loading--light.png differ diff --git a/frontend/__snapshots__/scenes-app-posthog-ai--generation-failure-thread--dark.png b/frontend/__snapshots__/scenes-app-posthog-ai--generation-failure-thread--dark.png index 933f985a26089..13ae32fae04e7 100644 Binary files a/frontend/__snapshots__/scenes-app-posthog-ai--generation-failure-thread--dark.png and b/frontend/__snapshots__/scenes-app-posthog-ai--generation-failure-thread--dark.png differ diff --git a/frontend/__snapshots__/scenes-app-posthog-ai--generation-failure-thread--light.png b/frontend/__snapshots__/scenes-app-posthog-ai--generation-failure-thread--light.png index 9a05600b2719a..9c431c04465b9 100644 Binary files a/frontend/__snapshots__/scenes-app-posthog-ai--generation-failure-thread--light.png and b/frontend/__snapshots__/scenes-app-posthog-ai--generation-failure-thread--light.png differ diff --git a/frontend/__snapshots__/scenes-app-posthog-ai--max-instance-with-contextual-tools--dark.png b/frontend/__snapshots__/scenes-app-posthog-ai--max-instance-with-contextual-tools--dark.png index 5bd66c084e88f..218b849f0c23c 100644 Binary files a/frontend/__snapshots__/scenes-app-posthog-ai--max-instance-with-contextual-tools--dark.png and b/frontend/__snapshots__/scenes-app-posthog-ai--max-instance-with-contextual-tools--dark.png differ diff --git a/frontend/__snapshots__/scenes-app-posthog-ai--max-instance-with-contextual-tools--light.png b/frontend/__snapshots__/scenes-app-posthog-ai--max-instance-with-contextual-tools--light.png index 7eaa3954b34e0..145c2384bedb8 100644 Binary files a/frontend/__snapshots__/scenes-app-posthog-ai--max-instance-with-contextual-tools--light.png and b/frontend/__snapshots__/scenes-app-posthog-ai--max-instance-with-contextual-tools--light.png differ diff --git a/frontend/__snapshots__/scenes-app-posthog-ai--multi-visualization-in-thread--dark.png b/frontend/__snapshots__/scenes-app-posthog-ai--multi-visualization-in-thread--dark.png index 31f1f46d78888..4f78fdfc91b81 100644 Binary files a/frontend/__snapshots__/scenes-app-posthog-ai--multi-visualization-in-thread--dark.png and b/frontend/__snapshots__/scenes-app-posthog-ai--multi-visualization-in-thread--dark.png differ diff --git a/frontend/__snapshots__/scenes-app-posthog-ai--multi-visualization-in-thread--light.png b/frontend/__snapshots__/scenes-app-posthog-ai--multi-visualization-in-thread--light.png index 34125140ceedc..c790774a5892b 100644 Binary files a/frontend/__snapshots__/scenes-app-posthog-ai--multi-visualization-in-thread--light.png and b/frontend/__snapshots__/scenes-app-posthog-ai--multi-visualization-in-thread--light.png differ diff --git a/frontend/__snapshots__/scenes-app-posthog-ai--notebook-update-component--dark.png b/frontend/__snapshots__/scenes-app-posthog-ai--notebook-update-component--dark.png index 26a5545ae6f06..ccb9649ec6d56 100644 Binary files a/frontend/__snapshots__/scenes-app-posthog-ai--notebook-update-component--dark.png and b/frontend/__snapshots__/scenes-app-posthog-ai--notebook-update-component--dark.png differ diff --git a/frontend/__snapshots__/scenes-app-posthog-ai--notebook-update-component--light.png b/frontend/__snapshots__/scenes-app-posthog-ai--notebook-update-component--light.png index e526b62af0d02..23ce79f9d067a 100644 Binary files a/frontend/__snapshots__/scenes-app-posthog-ai--notebook-update-component--light.png and b/frontend/__snapshots__/scenes-app-posthog-ai--notebook-update-component--light.png differ diff --git a/frontend/__snapshots__/scenes-app-posthog-ai--planning-component--dark.png b/frontend/__snapshots__/scenes-app-posthog-ai--planning-component--dark.png index b695479bc1f2e..15922c030a426 100644 Binary files a/frontend/__snapshots__/scenes-app-posthog-ai--planning-component--dark.png and b/frontend/__snapshots__/scenes-app-posthog-ai--planning-component--dark.png differ diff --git a/frontend/__snapshots__/scenes-app-posthog-ai--planning-component--light.png b/frontend/__snapshots__/scenes-app-posthog-ai--planning-component--light.png index 838c04b241db9..e181309c0f0fa 100644 Binary files a/frontend/__snapshots__/scenes-app-posthog-ai--planning-component--light.png and b/frontend/__snapshots__/scenes-app-posthog-ai--planning-component--light.png differ diff --git a/frontend/__snapshots__/scenes-app-posthog-ai--reasoning-component--dark.png b/frontend/__snapshots__/scenes-app-posthog-ai--reasoning-component--dark.png index 2c559ae192108..16a43801e6646 100644 Binary files a/frontend/__snapshots__/scenes-app-posthog-ai--reasoning-component--dark.png and b/frontend/__snapshots__/scenes-app-posthog-ai--reasoning-component--dark.png differ diff --git a/frontend/__snapshots__/scenes-app-posthog-ai--reasoning-component--light.png b/frontend/__snapshots__/scenes-app-posthog-ai--reasoning-component--light.png index bcedecf86f07b..e49a68673c0dc 100644 Binary files a/frontend/__snapshots__/scenes-app-posthog-ai--reasoning-component--light.png and b/frontend/__snapshots__/scenes-app-posthog-ai--reasoning-component--light.png differ diff --git a/frontend/__snapshots__/scenes-app-posthog-ai--search-session-recordings-empty--dark.png b/frontend/__snapshots__/scenes-app-posthog-ai--search-session-recordings-empty--dark.png index 6ff5581922af8..de6497d5f00b2 100644 Binary files a/frontend/__snapshots__/scenes-app-posthog-ai--search-session-recordings-empty--dark.png and b/frontend/__snapshots__/scenes-app-posthog-ai--search-session-recordings-empty--dark.png differ diff --git a/frontend/__snapshots__/scenes-app-posthog-ai--search-session-recordings-empty--light.png b/frontend/__snapshots__/scenes-app-posthog-ai--search-session-recordings-empty--light.png index efa2f09556100..9959d42a5dca8 100644 Binary files a/frontend/__snapshots__/scenes-app-posthog-ai--search-session-recordings-empty--light.png and b/frontend/__snapshots__/scenes-app-posthog-ai--search-session-recordings-empty--light.png differ diff --git a/frontend/__snapshots__/scenes-app-posthog-ai--search-session-recordings-with-results--dark.png b/frontend/__snapshots__/scenes-app-posthog-ai--search-session-recordings-with-results--dark.png index 4811e40e6b31e..33aac6224ecab 100644 Binary files a/frontend/__snapshots__/scenes-app-posthog-ai--search-session-recordings-with-results--dark.png and b/frontend/__snapshots__/scenes-app-posthog-ai--search-session-recordings-with-results--dark.png differ diff --git a/frontend/__snapshots__/scenes-app-posthog-ai--search-session-recordings-with-results--light.png b/frontend/__snapshots__/scenes-app-posthog-ai--search-session-recordings-with-results--light.png index a026d0216ceac..c25809d5ad905 100644 Binary files a/frontend/__snapshots__/scenes-app-posthog-ai--search-session-recordings-with-results--light.png and b/frontend/__snapshots__/scenes-app-posthog-ai--search-session-recordings-with-results--light.png differ diff --git a/frontend/__snapshots__/scenes-app-posthog-ai--shared-thread--dark.png b/frontend/__snapshots__/scenes-app-posthog-ai--shared-thread--dark.png new file mode 100644 index 0000000000000..99729cbe063bd Binary files /dev/null and b/frontend/__snapshots__/scenes-app-posthog-ai--shared-thread--dark.png differ diff --git a/frontend/__snapshots__/scenes-app-posthog-ai--shared-thread--light.png b/frontend/__snapshots__/scenes-app-posthog-ai--shared-thread--light.png new file mode 100644 index 0000000000000..7ede06fe5bb17 Binary files /dev/null and b/frontend/__snapshots__/scenes-app-posthog-ai--shared-thread--light.png differ diff --git a/frontend/__snapshots__/scenes-app-posthog-ai--task-execution-component--dark.png b/frontend/__snapshots__/scenes-app-posthog-ai--task-execution-component--dark.png index 839fef99fc838..4863b9073372b 100644 Binary files a/frontend/__snapshots__/scenes-app-posthog-ai--task-execution-component--dark.png and b/frontend/__snapshots__/scenes-app-posthog-ai--task-execution-component--dark.png differ diff --git a/frontend/__snapshots__/scenes-app-posthog-ai--task-execution-component--light.png b/frontend/__snapshots__/scenes-app-posthog-ai--task-execution-component--light.png index d5ef07d1ab6fa..0bfd254752aea 100644 Binary files a/frontend/__snapshots__/scenes-app-posthog-ai--task-execution-component--light.png and b/frontend/__snapshots__/scenes-app-posthog-ai--task-execution-component--light.png differ diff --git a/frontend/__snapshots__/scenes-app-posthog-ai--task-execution-with-failure--dark.png b/frontend/__snapshots__/scenes-app-posthog-ai--task-execution-with-failure--dark.png index 7f907277cbd56..f39fa255f9d0d 100644 Binary files a/frontend/__snapshots__/scenes-app-posthog-ai--task-execution-with-failure--dark.png and b/frontend/__snapshots__/scenes-app-posthog-ai--task-execution-with-failure--dark.png differ diff --git a/frontend/__snapshots__/scenes-app-posthog-ai--task-execution-with-failure--light.png b/frontend/__snapshots__/scenes-app-posthog-ai--task-execution-with-failure--light.png index 8d6f0fdcfd9b5..e37e6f890e814 100644 Binary files a/frontend/__snapshots__/scenes-app-posthog-ai--task-execution-with-failure--light.png and b/frontend/__snapshots__/scenes-app-posthog-ai--task-execution-with-failure--light.png differ diff --git a/frontend/__snapshots__/scenes-app-posthog-ai--thread--dark.png b/frontend/__snapshots__/scenes-app-posthog-ai--thread--dark.png index 0ab9e45763960..24aa085ea390a 100644 Binary files a/frontend/__snapshots__/scenes-app-posthog-ai--thread--dark.png and b/frontend/__snapshots__/scenes-app-posthog-ai--thread--dark.png differ diff --git a/frontend/__snapshots__/scenes-app-posthog-ai--thread--light.png b/frontend/__snapshots__/scenes-app-posthog-ai--thread--light.png index efe24e2a29f6c..272c4ae4a0ad2 100644 Binary files a/frontend/__snapshots__/scenes-app-posthog-ai--thread--light.png and b/frontend/__snapshots__/scenes-app-posthog-ai--thread--light.png differ diff --git a/frontend/__snapshots__/scenes-app-posthog-ai--thread-scrolls-to-bottom-on-new-messages--dark.png b/frontend/__snapshots__/scenes-app-posthog-ai--thread-scrolls-to-bottom-on-new-messages--dark.png index 7f098f3117736..51ce45ce54621 100644 Binary files a/frontend/__snapshots__/scenes-app-posthog-ai--thread-scrolls-to-bottom-on-new-messages--dark.png and b/frontend/__snapshots__/scenes-app-posthog-ai--thread-scrolls-to-bottom-on-new-messages--dark.png differ diff --git a/frontend/__snapshots__/scenes-app-posthog-ai--thread-scrolls-to-bottom-on-new-messages--light.png b/frontend/__snapshots__/scenes-app-posthog-ai--thread-scrolls-to-bottom-on-new-messages--light.png index c7ff9d7e0bb24..9ec05ab48eac2 100644 Binary files a/frontend/__snapshots__/scenes-app-posthog-ai--thread-scrolls-to-bottom-on-new-messages--light.png and b/frontend/__snapshots__/scenes-app-posthog-ai--thread-scrolls-to-bottom-on-new-messages--light.png differ diff --git a/frontend/__snapshots__/scenes-app-posthog-ai--thread-with-conversation-loading--dark.png b/frontend/__snapshots__/scenes-app-posthog-ai--thread-with-conversation-loading--dark.png index 2821f68dccaba..48ca8a4d8c613 100644 Binary files a/frontend/__snapshots__/scenes-app-posthog-ai--thread-with-conversation-loading--dark.png and b/frontend/__snapshots__/scenes-app-posthog-ai--thread-with-conversation-loading--dark.png differ diff --git a/frontend/__snapshots__/scenes-app-posthog-ai--thread-with-conversation-loading--light.png b/frontend/__snapshots__/scenes-app-posthog-ai--thread-with-conversation-loading--light.png index f78fe64652d17..f263739b8b5e3 100644 Binary files a/frontend/__snapshots__/scenes-app-posthog-ai--thread-with-conversation-loading--light.png and b/frontend/__snapshots__/scenes-app-posthog-ai--thread-with-conversation-loading--light.png differ diff --git a/frontend/__snapshots__/scenes-app-posthog-ai--thread-with-empty-conversation--dark.png b/frontend/__snapshots__/scenes-app-posthog-ai--thread-with-empty-conversation--dark.png index 81211138a34dc..5b9afdeba59a9 100644 Binary files a/frontend/__snapshots__/scenes-app-posthog-ai--thread-with-empty-conversation--dark.png and b/frontend/__snapshots__/scenes-app-posthog-ai--thread-with-empty-conversation--dark.png differ diff --git a/frontend/__snapshots__/scenes-app-posthog-ai--thread-with-empty-conversation--light.png b/frontend/__snapshots__/scenes-app-posthog-ai--thread-with-empty-conversation--light.png index bc6b5fa3a75e3..b32f96e8c4ded 100644 Binary files a/frontend/__snapshots__/scenes-app-posthog-ai--thread-with-empty-conversation--light.png and b/frontend/__snapshots__/scenes-app-posthog-ai--thread-with-empty-conversation--light.png differ diff --git a/frontend/__snapshots__/scenes-app-posthog-ai--thread-with-failed-generation--dark.png b/frontend/__snapshots__/scenes-app-posthog-ai--thread-with-failed-generation--dark.png index 64577d14b0877..074ba8e894225 100644 Binary files a/frontend/__snapshots__/scenes-app-posthog-ai--thread-with-failed-generation--dark.png and b/frontend/__snapshots__/scenes-app-posthog-ai--thread-with-failed-generation--dark.png differ diff --git a/frontend/__snapshots__/scenes-app-posthog-ai--thread-with-failed-generation--light.png b/frontend/__snapshots__/scenes-app-posthog-ai--thread-with-failed-generation--light.png index cd1aff564b748..2f8f3f0dcf79c 100644 Binary files a/frontend/__snapshots__/scenes-app-posthog-ai--thread-with-failed-generation--light.png and b/frontend/__snapshots__/scenes-app-posthog-ai--thread-with-failed-generation--light.png differ diff --git a/frontend/__snapshots__/scenes-app-posthog-ai--thread-with-form--dark.png b/frontend/__snapshots__/scenes-app-posthog-ai--thread-with-form--dark.png index a61c6a36dfab0..5452f4d3bd6eb 100644 Binary files a/frontend/__snapshots__/scenes-app-posthog-ai--thread-with-form--dark.png and b/frontend/__snapshots__/scenes-app-posthog-ai--thread-with-form--dark.png differ diff --git a/frontend/__snapshots__/scenes-app-posthog-ai--thread-with-form--light.png b/frontend/__snapshots__/scenes-app-posthog-ai--thread-with-form--light.png index 895e3e6193dbe..df1b8d918f470 100644 Binary files a/frontend/__snapshots__/scenes-app-posthog-ai--thread-with-form--light.png and b/frontend/__snapshots__/scenes-app-posthog-ai--thread-with-form--light.png differ diff --git a/frontend/__snapshots__/scenes-app-posthog-ai--thread-with-rate-limit--dark.png b/frontend/__snapshots__/scenes-app-posthog-ai--thread-with-rate-limit--dark.png index e71a57b85eaca..48ccbf47ee5a2 100644 Binary files a/frontend/__snapshots__/scenes-app-posthog-ai--thread-with-rate-limit--dark.png and b/frontend/__snapshots__/scenes-app-posthog-ai--thread-with-rate-limit--dark.png differ diff --git a/frontend/__snapshots__/scenes-app-posthog-ai--thread-with-rate-limit--light.png b/frontend/__snapshots__/scenes-app-posthog-ai--thread-with-rate-limit--light.png index 05728610dfa6e..ca8df322f74b4 100644 Binary files a/frontend/__snapshots__/scenes-app-posthog-ai--thread-with-rate-limit--light.png and b/frontend/__snapshots__/scenes-app-posthog-ai--thread-with-rate-limit--light.png differ diff --git a/frontend/__snapshots__/scenes-app-posthog-ai--thread-with-rate-limit-no-retry-after--dark.png b/frontend/__snapshots__/scenes-app-posthog-ai--thread-with-rate-limit-no-retry-after--dark.png index f01cc9756a6f4..8270244cfac70 100644 Binary files a/frontend/__snapshots__/scenes-app-posthog-ai--thread-with-rate-limit-no-retry-after--dark.png and b/frontend/__snapshots__/scenes-app-posthog-ai--thread-with-rate-limit-no-retry-after--dark.png differ diff --git a/frontend/__snapshots__/scenes-app-posthog-ai--thread-with-rate-limit-no-retry-after--light.png b/frontend/__snapshots__/scenes-app-posthog-ai--thread-with-rate-limit-no-retry-after--light.png index 71338473e1b39..050799b7c69af 100644 Binary files a/frontend/__snapshots__/scenes-app-posthog-ai--thread-with-rate-limit-no-retry-after--light.png and b/frontend/__snapshots__/scenes-app-posthog-ai--thread-with-rate-limit-no-retry-after--light.png differ diff --git a/frontend/__snapshots__/scenes-app-posthog-ai--thread-with-sql-query-overflow--dark.png b/frontend/__snapshots__/scenes-app-posthog-ai--thread-with-sql-query-overflow--dark.png index 58423b9c2c0fe..3697af1ce1a8d 100644 Binary files a/frontend/__snapshots__/scenes-app-posthog-ai--thread-with-sql-query-overflow--dark.png and b/frontend/__snapshots__/scenes-app-posthog-ai--thread-with-sql-query-overflow--dark.png differ diff --git a/frontend/__snapshots__/scenes-app-posthog-ai--thread-with-sql-query-overflow--light.png b/frontend/__snapshots__/scenes-app-posthog-ai--thread-with-sql-query-overflow--light.png index bc927a25b8ecc..67d32445b4329 100644 Binary files a/frontend/__snapshots__/scenes-app-posthog-ai--thread-with-sql-query-overflow--light.png and b/frontend/__snapshots__/scenes-app-posthog-ai--thread-with-sql-query-overflow--light.png differ diff --git a/frontend/__snapshots__/scenes-app-posthog-ai--welcome--dark.png b/frontend/__snapshots__/scenes-app-posthog-ai--welcome--dark.png index 5358695a7c511..ba9086c0a1dc4 100644 Binary files a/frontend/__snapshots__/scenes-app-posthog-ai--welcome--dark.png and b/frontend/__snapshots__/scenes-app-posthog-ai--welcome--dark.png differ diff --git a/frontend/__snapshots__/scenes-app-posthog-ai--welcome--light.png b/frontend/__snapshots__/scenes-app-posthog-ai--welcome--light.png index 7d4731f9e6204..d89ef565ffe78 100644 Binary files a/frontend/__snapshots__/scenes-app-posthog-ai--welcome--light.png and b/frontend/__snapshots__/scenes-app-posthog-ai--welcome--light.png differ diff --git a/frontend/__snapshots__/scenes-app-posthog-ai--welcome-feature-preview-auto-enrolled--dark.png b/frontend/__snapshots__/scenes-app-posthog-ai--welcome-feature-preview-auto-enrolled--dark.png index c4bc7736e8957..d261a6ea2dd53 100644 Binary files a/frontend/__snapshots__/scenes-app-posthog-ai--welcome-feature-preview-auto-enrolled--dark.png and b/frontend/__snapshots__/scenes-app-posthog-ai--welcome-feature-preview-auto-enrolled--dark.png differ diff --git a/frontend/__snapshots__/scenes-app-posthog-ai--welcome-feature-preview-auto-enrolled--light.png b/frontend/__snapshots__/scenes-app-posthog-ai--welcome-feature-preview-auto-enrolled--light.png index f9a3c62c8422b..d722db7173a65 100644 Binary files a/frontend/__snapshots__/scenes-app-posthog-ai--welcome-feature-preview-auto-enrolled--light.png and b/frontend/__snapshots__/scenes-app-posthog-ai--welcome-feature-preview-auto-enrolled--light.png differ diff --git a/frontend/src/scenes/max/Max.stories.tsx b/frontend/src/scenes/max/Max.stories.tsx index 49aafe1642f76..e272becdd0474 100644 --- a/frontend/src/scenes/max/Max.stories.tsx +++ b/frontend/src/scenes/max/Max.stories.tsx @@ -9,7 +9,7 @@ import { longResponseChunk, sqlQueryResponseChunk, } from './__mocks__/chatResponse.mocks' -import { MOCK_DEFAULT_ORGANIZATION } from 'lib/api.mock' +import { MOCK_DEFAULT_BASIC_USER, MOCK_DEFAULT_ORGANIZATION } from 'lib/api.mock' import { Meta, StoryFn } from '@storybook/react' import { useActions, useValues } from 'kea' @@ -62,6 +62,7 @@ const meta: Meta = { title: 'Test Conversation', created_at: '2025-04-29T17:44:21.654307Z', updated_at: '2025-04-29T17:44:29.184791Z', + user: MOCK_DEFAULT_BASIC_USER, messages: [], }, ], @@ -360,6 +361,62 @@ export const ThreadWithEmptyConversation: StoryFn = () => { return