Files
odysseus/tests/test_deep_research_date_context.py
lekt8 ce7f5dbbdd Inject current date into deep research planning and query prompts (#1347)
Deep research generated search queries from the LLM's training-cutoff
knowledge, so it emitted stale-year queries like "best Python tutorials
2025" when the actual year is later (issue #1341). The chat/agent path
already grounds the model with "Today is ..." (src/agent_loop.py); the
deep research planning and query-generation prompts had no equivalent.

Add a small current_date_context() helper and prepend it at the plan and
query-generation prompt sites (and the research_handler plan preview path
that reuses RESEARCH_PLAN_PROMPT). System-TZ local, portable strftime.

Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-03 03:00:52 +09:00

69 lines
2.1 KiB
Python

"""Regression tests for issue #1341 — deep research used the model's
training-cutoff year (e.g. "best Python tutorials 2025") because the
query-generation and planning prompts never told the LLM the current date.
The chat/agent path already injects "Today is ..." (src/agent_loop.py); deep
research had no equivalent. These tests pin that the current year now reaches
the LLM at both the planning and query-generation steps, without needing a live
LLM or DB.
"""
import asyncio
from datetime import datetime
from src.deep_research import (
DeepResearcher,
current_date_context,
RESEARCH_PLAN_PROMPT,
)
def _this_year() -> str:
return datetime.now().astimezone().strftime("%Y")
def test_current_date_context_names_the_real_year():
ctx = current_date_context()
assert _this_year() in ctx
# It must actively steer the model away from training-data years.
assert "training data" in ctx.lower()
def test_generate_queries_prompt_carries_the_current_year():
# Build without the heavy __init__; _generate_queries only needs these.
r = DeepResearcher.__new__(DeepResearcher)
r.research_plan = ""
r.queries_used = set()
seen = {}
async def _fake_llm(messages, **kwargs):
seen["prompt"] = messages[0]["content"]
return '["python tutorials", "python guides"]'
r._llm = _fake_llm
queries = asyncio.run(r._generate_queries("best python tutorials", "", 1))
assert queries # sanity: the JSON array parsed
# The fix: the real current year is in the prompt the LLM actually sees.
assert _this_year() in seen["prompt"]
def test_plan_prompt_carries_the_current_year():
r = DeepResearcher.__new__(DeepResearcher)
seen = {}
async def _fake_llm(messages, **kwargs):
seen["prompt"] = messages[0]["content"]
return "{}"
r._llm = _fake_llm
asyncio.run(r._create_plan("what changed this year"))
assert _this_year() in seen["prompt"]
# The base template itself stays year-agnostic; the year comes from the
# prepended context, proving the wiring (not a hard-coded prompt edit).
assert _this_year() not in RESEARCH_PLAN_PROMPT