From 088ee2090e61b0592404b95a9a349b6e83ccec92 Mon Sep 17 00:00:00 2001 From: "Kris Hatcher (he/him)" Date: Fri, 24 Apr 2026 14:04:10 -0400 Subject: [PATCH 1/5] fix: correct placement for conversation_id param Move parameter into body and rename to align with expectation for Xpert API Services. --- learning_assistant/utils.py | 9 +++++---- tests/test_utils.py | 7 +++---- 2 files changed, 8 insertions(+), 8 deletions(-) diff --git a/learning_assistant/utils.py b/learning_assistant/utils.py index 2834f9d..3eac576 100644 --- a/learning_assistant/utils.py +++ b/learning_assistant/utils.py @@ -57,7 +57,7 @@ def get_reduced_message_list(prompt_template, message_list): return new_message_list -def create_request_body(prompt_template, message_list, user_id): +def create_request_body(prompt_template, message_list, user_id, convo_id): """ Form request body to be passed to the chat endpoint. """ @@ -73,6 +73,7 @@ def create_request_body(prompt_template, message_list, user_id): 'system_message': prompt_template, 'messages': messages, 'external_id': str(user_id), + 'conversation_id': convo_id, } return response_body @@ -107,12 +108,12 @@ def get_chat_response(prompt_template, message_list, user_id, course_run_id): completion_endpoint = getattr(settings, 'CHAT_COMPLETION_API_V2', None) if v2_endpoint_enabled() \ else getattr(settings, 'CHAT_COMPLETION_API', None) if completion_endpoint: - conversation_history_id = create_conversation_history_id(user_id, course_run_id) - headers = {'Content-Type': 'application/json', 'Conversation-History-ID': conversation_history_id} + headers = {'Content-Type': 'application/json'} connect_timeout = getattr(settings, 'CHAT_COMPLETION_API_CONNECT_TIMEOUT', 1) read_timeout = getattr(settings, 'CHAT_COMPLETION_API_READ_TIMEOUT', 15) - body = create_request_body(prompt_template, message_list, user_id) + conversation_history_id = create_conversation_history_id(user_id, course_run_id) + body = create_request_body(prompt_template, message_list, user_id, conversation_history_id) try: response = requests.post( diff --git a/tests/test_utils.py b/tests/test_utils.py index 9ada293..850cccd 100644 --- a/tests/test_utils.py +++ b/tests/test_utils.py @@ -108,12 +108,10 @@ def test_timeout(self, exception, mock_requests): def test_post_request_structure(self, mock_requests): mock_requests.post = MagicMock() - mock_convo_hist_id = str(uuid.uuid5(uuid.NAMESPACE_URL, f'{self.user_id}_{self.course_id}')) - completion_endpoint = settings.CHAT_COMPLETION_API connect_timeout = settings.CHAT_COMPLETION_API_CONNECT_TIMEOUT read_timeout = settings.CHAT_COMPLETION_API_READ_TIMEOUT - headers = {'Content-Type': 'application/json', 'Conversation-History-ID': mock_convo_hist_id} + headers = {'Content-Type': 'application/json'} response_body = { 'message_list': [{'role': 'system', 'content': self.prompt_template}] + self.message_list, @@ -138,13 +136,14 @@ def test_post_request_structure_v2_endpoint(self, mock_requests, mock_v2_enabled completion_endpoint_v2 = settings.CHAT_COMPLETION_API_V2 connect_timeout = settings.CHAT_COMPLETION_API_CONNECT_TIMEOUT read_timeout = settings.CHAT_COMPLETION_API_READ_TIMEOUT - headers = {'Content-Type': 'application/json', 'Conversation-History-ID': mock_convo_hist_id} + headers = {'Content-Type': 'application/json'} response_body = { 'client_id': 'edx_olc_la', 'system_message': self.prompt_template, 'messages': self.message_list, 'external_id': self.user_id, + 'conversation_id': mock_convo_hist_id, } self.get_response() From 2c1f14db84699822b1ba94f886c5c01a50fbd39c Mon Sep 17 00:00:00 2001 From: "Kris Hatcher (he/him)" Date: Fri, 24 Apr 2026 14:04:56 -0400 Subject: [PATCH 2/5] fix: avoid potential collisions Following recommendation from Copilot: https://github.com/edx/learning-assistant/pull/222/changes#r3100416910 --- learning_assistant/utils.py | 4 ++-- tests/test_utils.py | 3 ++- 2 files changed, 4 insertions(+), 3 deletions(-) diff --git a/learning_assistant/utils.py b/learning_assistant/utils.py index 3eac576..73714a6 100644 --- a/learning_assistant/utils.py +++ b/learning_assistant/utils.py @@ -90,12 +90,12 @@ def create_conversation_history_id(user_id, course_run_id): Returns: * str: the conversation history id """ - convo_hist_seed = f'{user_id}_{course_run_id}' + convo_hist_seed = json.dumps([str(user_id), str(course_run_id)], separators=(',', ':')) # Use a pre-defined namespace (e.g., DNS, URL, OID, or X500) namespace = uuid.NAMESPACE_URL - # Generate the same UUID every time for the same string + # Generate the same UUID every time for the same user/course_run pair deterministic_uuid = uuid.uuid5(namespace, convo_hist_seed) return str(deterministic_uuid) diff --git a/tests/test_utils.py b/tests/test_utils.py index 850cccd..ccd60df 100644 --- a/tests/test_utils.py +++ b/tests/test_utils.py @@ -131,7 +131,8 @@ def test_post_request_structure_v2_endpoint(self, mock_requests, mock_v2_enabled mock_requests.post = MagicMock() mock_v2_enabled.return_value = True - mock_convo_hist_id = str(uuid.uuid5(uuid.NAMESPACE_URL, f'{self.user_id}_{self.course_id}')) + mock_convo_id_seed = json.dumps([str(user_id), str(course_run_id)], separators=(',', ':')) + mock_convo_hist_id = str(uuid.uuid5(uuid.NAMESPACE_URL, str(mock_convo_id_seed)) completion_endpoint_v2 = settings.CHAT_COMPLETION_API_V2 connect_timeout = settings.CHAT_COMPLETION_API_CONNECT_TIMEOUT From 7acff909c7a36fb864505291b82a14b55dd6edce Mon Sep 17 00:00:00 2001 From: "Kris Hatcher (he/him)" Date: Fri, 24 Apr 2026 14:09:08 -0400 Subject: [PATCH 3/5] fix: correct formatting error --- tests/test_utils.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/test_utils.py b/tests/test_utils.py index ccd60df..5ba0f01 100644 --- a/tests/test_utils.py +++ b/tests/test_utils.py @@ -132,7 +132,7 @@ def test_post_request_structure_v2_endpoint(self, mock_requests, mock_v2_enabled mock_v2_enabled.return_value = True mock_convo_id_seed = json.dumps([str(user_id), str(course_run_id)], separators=(',', ':')) - mock_convo_hist_id = str(uuid.uuid5(uuid.NAMESPACE_URL, str(mock_convo_id_seed)) + mock_convo_hist_id = str(uuid.uuid5(uuid.NAMESPACE_URL, str(mock_convo_id_seed))) completion_endpoint_v2 = settings.CHAT_COMPLETION_API_V2 connect_timeout = settings.CHAT_COMPLETION_API_CONNECT_TIMEOUT From 15c359a8783f5abdf2b2a969280d1c2c5cea2e53 Mon Sep 17 00:00:00 2001 From: "Kris Hatcher (he/him)" Date: Fri, 24 Apr 2026 14:11:52 -0400 Subject: [PATCH 4/5] fix: reference correct variables --- tests/test_utils.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/test_utils.py b/tests/test_utils.py index 5ba0f01..b4b6f5f 100644 --- a/tests/test_utils.py +++ b/tests/test_utils.py @@ -131,7 +131,7 @@ def test_post_request_structure_v2_endpoint(self, mock_requests, mock_v2_enabled mock_requests.post = MagicMock() mock_v2_enabled.return_value = True - mock_convo_id_seed = json.dumps([str(user_id), str(course_run_id)], separators=(',', ':')) + mock_convo_id_seed = json.dumps([str(self.user_id), str(self.course_id)], separators=(',', ':')) mock_convo_hist_id = str(uuid.uuid5(uuid.NAMESPACE_URL, str(mock_convo_id_seed))) completion_endpoint_v2 = settings.CHAT_COMPLETION_API_V2 From dcd4065aee3555e1ede00f734c92c1923f6e6881 Mon Sep 17 00:00:00 2001 From: "Kris Hatcher (he/him)" Date: Fri, 24 Apr 2026 14:15:20 -0400 Subject: [PATCH 5/5] chore: update changelog for version 4.11.5 --- CHANGELOG.rst | 4 ++++ learning_assistant/__init__.py | 2 +- 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.rst b/CHANGELOG.rst index 6a551d6..ed11d43 100644 --- a/CHANGELOG.rst +++ b/CHANGELOG.rst @@ -13,6 +13,10 @@ Change Log Unreleased ********** +4.11.5 - 2026-04-24 +******************* +* Fixes a bug where the Conversation-ID value was not being properly included in the API call to the Xpert backend, which caused learning assistant messages to not be included in downstream reports and analysis. + 4.11.4 - 2026-04-17 ******************* * To include additional, optional parameters so that learning assistant messages are included in downstream reports and analysis. diff --git a/learning_assistant/__init__.py b/learning_assistant/__init__.py index 9569505..59f3dcc 100644 --- a/learning_assistant/__init__.py +++ b/learning_assistant/__init__.py @@ -2,6 +2,6 @@ Plugin for a learning assistant backend, intended for use within edx-platform. """ -__version__ = '4.11.4' +__version__ = '4.11.5' default_app_config = 'learning_assistant.apps.LearningAssistantConfig' # pylint: disable=invalid-name