From c2b25721fc91f20f37fe3b07785d22af14490f2a Mon Sep 17 00:00:00 2001 From: Naragod Date: Wed, 19 Aug 2026 16:41:41 -0400 Subject: [PATCH 1/2] TICKET-535: Accept system_instructions alias in /chat --- src/markus_ai_server/server.py | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/markus_ai_server/server.py b/src/markus_ai_server/server.py index 5684740..533be16 100644 --- a/src/markus_ai_server/server.py +++ b/src/markus_ai_server/server.py @@ -272,7 +272,9 @@ def chat(): model = request.form.get('model', DEFAULT_MODEL) content = request.form.get('content', '') llama_mode = request.form.get('llama_mode', 'cli') - system_prompt = request.form.get('system_prompt') + # Accept either field name: callers send 'system_prompt', the ai_feedback + # RemoteModel sends 'system_instructions'. Prefer the former when both exist. + system_prompt = request.form.get('system_prompt') or request.form.get('system_instructions') image_files = list(request.files.values()) model_options = request.form.get('model_options') json_schema = request.form.get('json_schema') From 6625feb097b5c04d8d8304b8da408885a39ae07d Mon Sep 17 00:00:00 2001 From: Naragod Date: Wed, 19 Aug 2026 16:41:42 -0400 Subject: [PATCH 2/2] TICKET-535: Add tests for system prompt field aliasing --- test/test_system_prompt_api.py | 48 ++++++++++++++++++++++------------ 1 file changed, 31 insertions(+), 17 deletions(-) diff --git a/test/test_system_prompt_api.py b/test/test_system_prompt_api.py index 38899a3..62516b3 100644 --- a/test/test_system_prompt_api.py +++ b/test/test_system_prompt_api.py @@ -1,4 +1,3 @@ -import json from unittest.mock import patch import pytest @@ -6,6 +5,7 @@ TEST_MODEL = 'DeepSeek-V3-0324-UD-IQ2_XXS' TEST_SYSTEM_PROMPT = "You are a helpful coding assistant." TEST_USER_CONTENT = "Write a function" +MOCK_MODEL_ANSWER = "def function(): pass" class TestSystemPromptAPI: @@ -25,40 +25,54 @@ def client(self): with app.test_client() as client: yield client - @patch('markus_ai_server.server.REDIS_CONNECTION') - @patch('markus_ai_server.server.chat_with_model') - def test_api_with_system_prompt(self, mock_chat, mock_redis, client): - """Test /chat endpoint receives and passes system_prompt.""" + def _post_chat_and_assert_prompt_forwarded(self, client, mock_chat, mock_redis, form_fields, expected_prompt): + """POST /chat with a valid key and assert the resolved system prompt reaches the model.""" mock_redis.get.return_value = b'test_user' - mock_chat.return_value = "def function(): pass" + mock_chat.return_value = MOCK_MODEL_ANSWER response = client.post( '/chat', headers={'X-API-KEY': 'test-key'}, - data={'model': TEST_MODEL, 'content': TEST_USER_CONTENT, 'system_prompt': TEST_SYSTEM_PROMPT}, + data={'model': TEST_MODEL, 'content': TEST_USER_CONTENT, **form_fields}, ) assert response.status_code == 200 - mock_chat.assert_called_once_with( - TEST_MODEL, TEST_USER_CONTENT, 'cli', TEST_SYSTEM_PROMPT, [], json_schema=None, model_options=None + TEST_MODEL, TEST_USER_CONTENT, 'cli', expected_prompt, [], json_schema=None, model_options=None + ) + + @patch('markus_ai_server.server.REDIS_CONNECTION') + @patch('markus_ai_server.server.chat_with_model') + def test_api_with_system_prompt(self, mock_chat, mock_redis, client): + """Test /chat endpoint receives and passes system_prompt.""" + self._post_chat_and_assert_prompt_forwarded( + client, mock_chat, mock_redis, {'system_prompt': TEST_SYSTEM_PROMPT}, TEST_SYSTEM_PROMPT ) @patch('markus_ai_server.server.REDIS_CONNECTION') @patch('markus_ai_server.server.chat_with_model') def test_api_without_system_prompt(self, mock_chat, mock_redis, client): """Test /chat endpoint works without system_prompt.""" - mock_redis.get.return_value = b'test_user' - mock_chat.return_value = "def function(): pass" + self._post_chat_and_assert_prompt_forwarded(client, mock_chat, mock_redis, {}, None) - response = client.post( - '/chat', headers={'X-API-KEY': 'test-key'}, data={'model': TEST_MODEL, 'content': TEST_USER_CONTENT} + @patch('markus_ai_server.server.REDIS_CONNECTION') + @patch('markus_ai_server.server.chat_with_model') + def test_api_accepts_system_instructions_alias(self, mock_chat, mock_redis, client): + """The ai_feedback RemoteModel sends 'system_instructions'; it must be honored.""" + self._post_chat_and_assert_prompt_forwarded( + client, mock_chat, mock_redis, {'system_instructions': TEST_SYSTEM_PROMPT}, TEST_SYSTEM_PROMPT ) - assert response.status_code == 200 - - mock_chat.assert_called_once_with( - TEST_MODEL, TEST_USER_CONTENT, 'cli', None, [], model_options=None, json_schema=None + @patch('markus_ai_server.server.REDIS_CONNECTION') + @patch('markus_ai_server.server.chat_with_model') + def test_system_prompt_wins_over_alias(self, mock_chat, mock_redis, client): + """When both fields are sent, 'system_prompt' takes precedence.""" + self._post_chat_and_assert_prompt_forwarded( + client, + mock_chat, + mock_redis, + {'system_prompt': TEST_SYSTEM_PROMPT, 'system_instructions': 'ignored alias'}, + TEST_SYSTEM_PROMPT, ) @patch('markus_ai_server.server.REDIS_CONNECTION')