- Flask web app with Perplexity-style search + synthesis pipeline - Degoog → SearXNG → DuckDuckGo cascading search backends - Gemini LLM for query expansion + answer synthesis with citations - MCP server exposing search tools via stdio - 57 unit tests covering all modules
80 lines
2.9 KiB
Python
80 lines
2.9 KiB
Python
"""Tests for sibilla.prompts — prompt templates and builders."""
|
|
|
|
from sibilla.prompts import (
|
|
SYNTHESIS_SYSTEM_PROMPT,
|
|
FALLBACK_PROMPT,
|
|
QUERY_REWRITE_PROMPT,
|
|
build_synthesis_prompt,
|
|
)
|
|
|
|
|
|
class TestPromptTemplates:
|
|
"""Verify all prompt templates are non-empty and well-formed."""
|
|
|
|
def test_synthesis_system_prompt_not_empty(self):
|
|
assert len(SYNTHESIS_SYSTEM_PROMPT) > 50
|
|
assert "Sibilla" in SYNTHESIS_SYSTEM_PROMPT
|
|
assert "[1]" in SYNTHESIS_SYSTEM_PROMPT
|
|
|
|
def test_fallback_prompt_not_empty(self):
|
|
assert len(FALLBACK_PROMPT) > 20
|
|
assert "Sibilla" in FALLBACK_PROMPT
|
|
|
|
def test_query_rewrite_prompt_has_placeholder(self):
|
|
assert "{num_variants}" in QUERY_REWRITE_PROMPT
|
|
|
|
|
|
class TestBuildSynthesisPrompt:
|
|
"""Test build_synthesis_prompt with various inputs."""
|
|
|
|
def test_minimal_prompt(self):
|
|
sources = [
|
|
{"index": 1, "title": "Test", "url": "https://example.com", "content": "Hello world"}
|
|
]
|
|
prompt = build_synthesis_prompt("what is this?", sources)
|
|
|
|
assert "what is this?" in prompt
|
|
assert "Test" in prompt
|
|
assert "https://example.com" in prompt
|
|
assert "Hello world" in prompt
|
|
assert "[1]" in prompt
|
|
|
|
def test_multiple_sources(self):
|
|
sources = [
|
|
{"index": 1, "title": "A", "url": "https://a.com", "content": "Content A"},
|
|
{"index": 2, "title": "B", "url": "https://b.com", "content": "Content B"},
|
|
{"index": 3, "title": "C", "url": "https://c.com", "content": "Content C"},
|
|
]
|
|
prompt = build_synthesis_prompt("query", sources)
|
|
|
|
assert "--- Fonte [1] ---" in prompt
|
|
assert "--- Fonte [2] ---" in prompt
|
|
assert "--- Fonte [3] ---" in prompt
|
|
assert "Content A" in prompt
|
|
assert "Content B" in prompt
|
|
assert "Content C" in prompt
|
|
|
|
def test_with_date_context(self):
|
|
sources = [{"index": 1, "title": "X", "url": "https://x.com", "content": "Y"}]
|
|
prompt = build_synthesis_prompt("q", sources, date_context="Data: 16 Luglio 2026")
|
|
|
|
assert "16 Luglio 2026" in prompt
|
|
assert "Contesto temporale" in prompt
|
|
|
|
def test_empty_sources(self):
|
|
prompt = build_synthesis_prompt("query", [])
|
|
assert "query" in prompt
|
|
assert "### Fonti da utilizzare" in prompt
|
|
|
|
def test_source_missing_fields(self):
|
|
sources = [{"index": 1}] # missing title, url, content
|
|
prompt = build_synthesis_prompt("q", sources)
|
|
assert "Senza titolo" in prompt # fallback title
|
|
assert "[1]" in prompt
|
|
|
|
def test_source_with_snippet_fallback(self):
|
|
"""When 'content' is missing, fall back to 'snippet'."""
|
|
sources = [{"index": 1, "title": "T", "url": "https://t.com", "snippet": "snippet text"}]
|
|
prompt = build_synthesis_prompt("q", sources)
|
|
assert "snippet text" in prompt
|