From 3ace60024a2c5f6ff7aadb4653e5d42422f8d756 Mon Sep 17 00:00:00 2001 From: Br1an67 <932039080@qq.com> Date: Sun, 1 Mar 2026 14:42:00 +0800 Subject: [PATCH] fix: include conversation history in SQL prompt template The SQL code generation template was missing the previous conversation context that the Python template already includes. Multi-turn follow-up queries produced incorrect results because the LLM had no visibility into prior questions and answers. Add a PREVIOUS CONVERSATION block to generate_python_code_with_sql.tmpl that mirrors the existing behavior in generate_python_code.tmpl, gated behind a memory.count() > 1 check. Closes #1856 --- .../generate_python_code_with_sql.tmpl | 4 ++ ...st_generate_python_code_with_sql_prompt.py | 45 +++++++++++++++++++ 2 files changed, 49 insertions(+) diff --git a/pandasai/core/prompts/templates/generate_python_code_with_sql.tmpl b/pandasai/core/prompts/templates/generate_python_code_with_sql.tmpl index 53eb0e28e..9439b7074 100644 --- a/pandasai/core/prompts/templates/generate_python_code_with_sql.tmpl +++ b/pandasai/core/prompts/templates/generate_python_code_with_sql.tmpl @@ -21,6 +21,10 @@ import pandas as pd ``` {% endif %} {% include 'shared/vectordb_docs.tmpl' with context %} +{% if context.memory.count() > 1 %} +### PREVIOUS CONVERSATION +{{ context.memory.get_previous_conversation() }} +{% endif %} {{ context.memory.get_last_message() }} At the end, declare "result" variable as a dictionary of type and value in the following format: diff --git a/tests/unit_tests/core/prompts/test_generate_python_code_with_sql_prompt.py b/tests/unit_tests/core/prompts/test_generate_python_code_with_sql_prompt.py index d4a0efe31..b7b888fde 100644 --- a/tests/unit_tests/core/prompts/test_generate_python_code_with_sql_prompt.py +++ b/tests/unit_tests/core/prompts/test_generate_python_code_with_sql_prompt.py @@ -3,6 +3,7 @@ import pytest from pandasai.core.prompts import GeneratePythonCodeWithSQLPrompt +from pandasai.helpers.memory import Memory @pytest.fixture @@ -17,6 +18,17 @@ def mock_context(): return context +@pytest.fixture +def render_context(): + """Context with real Memory for template rendering tests.""" + context = Mock() + context.dfs = [] + context.skills = [] + context.config.direct_sql = True + context.vectorstore = None + return context + + def test_to_json(mock_context): """Test that to_json returns the expected structure with all required fields""" prompt = GeneratePythonCodeWithSQLPrompt(context=mock_context, output_type="code") @@ -46,3 +58,36 @@ def test_to_json(mock_context): assert result["config"]["direct_sql"] is True assert "output_type" in result["config"] assert result["config"]["output_type"] == "code" + + +def test_template_includes_previous_conversation(render_context): + """Test that the rendered template includes previous conversation history.""" + memory = Memory(memory_size=10) + memory.add("What is the average salary?", is_user=True) + memory.add('result = {"type": "number", "value": 50000}', is_user=False) + memory.add("Show me the top 5 earners", is_user=True) + render_context.memory = memory + + prompt = GeneratePythonCodeWithSQLPrompt( + context=render_context, last_code_generated=None, output_type="number" + ) + rendered = prompt.to_string() + + assert "PREVIOUS CONVERSATION" in rendered + assert "average salary" in rendered + assert "top 5 earners" in rendered + + +def test_template_no_previous_conversation_for_single_message(render_context): + """Test that single-message memory does not show PREVIOUS CONVERSATION.""" + memory = Memory(memory_size=10) + memory.add("What is the average salary?", is_user=True) + render_context.memory = memory + + prompt = GeneratePythonCodeWithSQLPrompt( + context=render_context, last_code_generated=None, output_type="number" + ) + rendered = prompt.to_string() + + assert "PREVIOUS CONVERSATION" not in rendered + assert "average salary" in rendered