feat(db): update history schema and generate prompt template for Package 4

Add chunks_retrieved_per_subq_count and chunks_filtered_per_subq_count columns to query_history table with safe ALTER TABLE migration. Replace generate template {question}/{context} placeholders with {context_sections} for per-sub-question organized context sections. Update Phase 3 test assertions to match new template and schema shapes.

Ultraworked with [Sisyphus](https://github.com/code-yeongyu/oh-my-openagent)

Co-authored-by: Sisyphus <clio-agent@sisyphuslabs.ai>
This commit is contained in:
Woody 2026-04-26 23:28:28 +08:00
parent 40393d81f8
commit 0ecae11bf8
5 changed files with 23 additions and 11 deletions

View File

@ -22,13 +22,14 @@ _SEED_FILTER = (
) )
_SEED_GENERATE = ( _SEED_GENERATE = (
"Question: {question}\n\n" "You must answer each sub-question using ONLY the document chunks provided for it.\n"
"Answer the question using ONLY these document chunks. " "Do not use any external knowledge.\n"
"Do not use any external knowledge. " "Format your answer as markdown sections — one section per sub-question.\n"
"Format your answer as bullet points. " "Each section should start with \"## Sub-question N: <the question>\"\n"
"Cite your sources inline using the exact bracket labels provided, " "Each section should contain 1-5 bullet points.\n"
"e.g. [filename, page N]. Place the citation at the end of each relevant point.\n\n" "Cite your sources inline using bracket labels, e.g. [filename, page N].\n"
"Document chunks:\n{context}\n\n" "Place the citation at the end of each relevant bullet point.\n\n"
"{context_sections}\n\n"
"Answer:" "Answer:"
) )
@ -113,6 +114,8 @@ def init_history_db(conn: sqlite3.Connection) -> None:
final_answer TEXT DEFAULT NULL, final_answer TEXT DEFAULT NULL,
sources TEXT DEFAULT NULL, sources TEXT DEFAULT NULL,
profile_used TEXT DEFAULT NULL, profile_used TEXT DEFAULT NULL,
chunks_retrieved_per_subq_count TEXT DEFAULT NULL,
chunks_filtered_per_subq_count TEXT DEFAULT NULL,
created_at TEXT NOT NULL DEFAULT (datetime('now')) created_at TEXT NOT NULL DEFAULT (datetime('now'))
) )
""") """)
@ -120,6 +123,13 @@ def init_history_db(conn: sqlite3.Connection) -> None:
CREATE INDEX IF NOT EXISTS idx_query_history_created_at CREATE INDEX IF NOT EXISTS idx_query_history_created_at
ON query_history(created_at DESC) ON query_history(created_at DESC)
""") """)
for col_name in ["chunks_retrieved_per_subq_count", "chunks_filtered_per_subq_count"]:
try:
conn.execute(
f"ALTER TABLE query_history ADD COLUMN {col_name} TEXT DEFAULT NULL"
)
except Exception:
pass
conn.commit() conn.commit()
logger.info("History DB tables initialized.") logger.info("History DB tables initialized.")

View File

@ -26,6 +26,7 @@ _INSERT_COLUMNS = (
"generate_prompt", "generator_time_ms", "generate_prompt", "generator_time_ms",
"total_time_ms", "total_time_ms",
"final_answer", "sources", "profile_used", "final_answer", "sources", "profile_used",
"chunks_retrieved_per_subq_count", "chunks_filtered_per_subq_count",
) )

View File

@ -47,6 +47,8 @@ CREATE TABLE IF NOT EXISTS query_history (
final_answer TEXT DEFAULT NULL, final_answer TEXT DEFAULT NULL,
sources TEXT DEFAULT NULL, sources TEXT DEFAULT NULL,
profile_used TEXT DEFAULT NULL, profile_used TEXT DEFAULT NULL,
chunks_retrieved_per_subq_count TEXT DEFAULT NULL,
chunks_filtered_per_subq_count TEXT DEFAULT NULL,
created_at TEXT NOT NULL DEFAULT (datetime('now')) created_at TEXT NOT NULL DEFAULT (datetime('now'))
) )
""" """

View File

@ -98,7 +98,7 @@ def test_get_profile_prompts_returns_all_three_steps(tmp_path):
assert set(prompts.keys()) == {"decompose", "filter", "generate"} assert set(prompts.keys()) == {"decompose", "filter", "generate"}
assert "{question}" in prompts["decompose"] assert "{question}" in prompts["decompose"]
assert "{question}" in prompts["filter"] assert "{question}" in prompts["filter"]
assert "{question}" in prompts["generate"] assert "{context_sections}" in prompts["generate"]
def test_get_profile_prompts_invalid_name_raises(tmp_path): def test_get_profile_prompts_invalid_name_raises(tmp_path):

View File

@ -311,7 +311,7 @@ def test_seed_default_profiles_contains_expected_templates(tmp_path, monkeypatch
assert "{question}" in filter_row["prompt_template"] assert "{question}" in filter_row["prompt_template"]
assert "{chunks}" in filter_row["prompt_template"] assert "{chunks}" in filter_row["prompt_template"]
# Generate must have {question} and {context} # Generate must have {context_sections}
generate_row = conn.execute( generate_row = conn.execute(
"""SELECT sp.prompt_template """SELECT sp.prompt_template
FROM system_prompts sp FROM system_prompts sp
@ -319,8 +319,7 @@ def test_seed_default_profiles_contains_expected_templates(tmp_path, monkeypatch
WHERE spp.name='A' AND sp.step_name='generate'""" WHERE spp.name='A' AND sp.step_name='generate'"""
).fetchone() ).fetchone()
assert generate_row is not None assert generate_row is not None
assert "{question}" in generate_row["prompt_template"] assert "{context_sections}" in generate_row["prompt_template"]
assert "{context}" in generate_row["prompt_template"]
conn.close() conn.close()