diff --git a/lib/cadet_web/controllers/chat_controller.ex b/lib/cadet_web/controllers/chat_controller.ex index e39271ea4..030c7cd3a 100644 --- a/lib/cadet_web/controllers/chat_controller.ex +++ b/lib/cadet_web/controllers/chat_controller.ex @@ -6,6 +6,7 @@ defmodule CadetWeb.ChatController do use PhoenixSwagger alias Cadet.Chatbot.{Conversation, LlmConversations} + @max_content_size 1000 def init_chat(conn, %{"section" => section, "initialContext" => initialContext}) do user = conn.assigns.current_user @@ -21,7 +22,8 @@ defmodule CadetWeb.ChatController do "conversation_init.json", %{ conversation_id: conversation.id, - last_message: conversation.messages |> List.last() + last_message: conversation.messages |> List.last(), + max_content_size: @max_content_size } ) @@ -51,13 +53,15 @@ defmodule CadetWeb.ChatController do response(200, "OK") response(400, "Missing or invalid parameter(s)") response(401, "Unauthorized") + response(422, "Message exceeds the maximum allowed length") response(500, "When OpenAI API returns an error") end def chat(conn, %{"conversationId" => conversation_id, "message" => user_message}) do user = conn.assigns.current_user - with {:ok, conversation} <- + with true <- String.length(user_message) <= @max_content_size || {:error, :message_too_long}, + {:ok, conversation} <- LlmConversations.get_conversation_for_user(user.id, conversation_id), {:ok, updated_conversation} <- LlmConversations.add_message(conversation, "user", user_message), @@ -85,6 +89,13 @@ defmodule CadetWeb.ChatController do send_resp(conn, 500, error_message) end else + {:error, :message_too_long} -> + send_resp( + conn, + :unprocessable_entity, + "Message exceeds the maximum allowed length of #{@max_content_size}" + ) + {:error, {:not_found, error_message}} -> send_resp(conn, :not_found, error_message) @@ -107,4 +118,6 @@ defmodule CadetWeb.ChatController do conversation.prepend_context ++ messages_payload end + + def max_content_length, do: @max_content_size end diff --git a/lib/cadet_web/views/chat_view.ex b/lib/cadet_web/views/chat_view.ex index b7db0bd2b..8dc72727a 100644 --- a/lib/cadet_web/views/chat_view.ex +++ b/lib/cadet_web/views/chat_view.ex @@ -1,8 +1,12 @@ defmodule CadetWeb.ChatView do use CadetWeb, :view - def render("conversation_init.json", %{conversation_id: id, last_message: last}) do - %{conversationId: id, response: last} + def render("conversation_init.json", %{ + conversation_id: id, + last_message: last, + max_content_size: size + }) do + %{conversationId: id, response: last, maxContentSize: size} end def render("conversation.json", %{conversation_id: id, response: response}) do diff --git a/test/cadet_web/controllers/chat_controller_test.exs b/test/cadet_web/controllers/chat_controller_test.exs index e5f63f164..b8c0c6808 100644 --- a/test/cadet_web/controllers/chat_controller_test.exs +++ b/test/cadet_web/controllers/chat_controller_test.exs @@ -76,6 +76,41 @@ defmodule CadetWeb.ChatControllerTest do end end + @tag authenticate: :student + @tag requires_setup: true + test "The content length is too long", + %{conn: conn, conversation_id: conversation_id} do + assert conversation_id != nil + max_message_length = ChatController.max_content_length() + message_exceed_length = String.duplicate("a", max_message_length + 1) + + conn = + post(conn, "/v2/chats/#{conversation_id}/message", %{ + "conversation_id" => conversation_id, + "message" => "#{message_exceed_length}" + }) + + assert response(conn, :unprocessable_entity) == + "Message exceeds the maximum allowed length of #{max_message_length}" + end + + @tag authenticate: :student + @tag requires_setup: true + test "The content length less than the maximum allowed length but conversation belongs to another user", + %{conn: conn, conversation_id: conversation_id} do + assert conversation_id != nil + max_message_length = ChatController.max_content_length() + message_exceed_length = String.duplicate("a", max_message_length) + + conn = + post(conn, "/v2/chats/#{conversation_id}/message", %{ + "conversation_id" => conversation_id, + "message" => "#{message_exceed_length}" + }) + + assert response(conn, :not_found) == "Conversation not found" + end + @tag authenticate: :student test "invalid conversation id", %{conn: conn} do conversation_id = "-1"