mirror of
https://github.com/pewdiepie-archdaemon/odysseus.git
synced 2026-06-16 17:55:26 -04:00
Route "read that report" to manage_research instead of the HTML render (#1375)
After a deep-research job completes, a follow-up like "check it out" / "read
that report" had the agent web_fetch the /api/research/report/{id} HTML render
(and then drift into unrelated searches) instead of reading the saved report
(issue #1363). The report text is already available via the manage_research
tool (action read), and action list returns ids most-recent-first, so the
agent can resolve "the recent report" itself.
Strengthen the manage_research instructions: read a finished report via
action list -> action read; do NOT web_fetch/app_api the report URL (it renders
HTML, not clean text) and do NOT start a fresh web_search just to read an
existing report. Annotate the app_api endpoint list to say the same.
Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -0,0 +1,67 @@
|
||||
"""Regression tests for issue #1363 — after a deep-research job finishes, asking
|
||||
the agent to "check it out / read that report" had it web_fetch the HTML report
|
||||
render (and drift into unrelated searches) instead of reading the saved report.
|
||||
|
||||
Per the maintainer's diagnosis the fix is in the agent/tool-routing path: a
|
||||
finished report should be read via `manage_research` (action read), resolving the
|
||||
most-recent id with `action list` when none is given — not by fetching the
|
||||
`/api/research/report/{id}` HTML.
|
||||
|
||||
These tests pin both halves:
|
||||
1. the read path the agent is told to use actually returns the report text for a
|
||||
saved `rp-...` id, and
|
||||
2. the agent instructions steer to `manage_research read` and away from
|
||||
web_fetching the HTML report.
|
||||
"""
|
||||
import json
|
||||
from pathlib import Path
|
||||
|
||||
import pytest
|
||||
|
||||
from src.tool_implementations import do_manage_research
|
||||
from src.agent_loop import TOOL_SECTIONS
|
||||
|
||||
_DATA_DIR = Path("data/deep_research")
|
||||
|
||||
|
||||
@pytest.fixture
|
||||
def saved_report():
|
||||
_DATA_DIR.mkdir(parents=True, exist_ok=True)
|
||||
rid = "rp-testreport1363"
|
||||
path = _DATA_DIR / f"{rid}.json"
|
||||
path.write_text(json.dumps({
|
||||
"query": "trending blender video ideas",
|
||||
"result": "## Findings\nShort-form Geometry Nodes tutorials are trending.",
|
||||
"sources": [{"title": "Example", "url": "https://example.com"}],
|
||||
"completed_at": 123,
|
||||
}), encoding="utf-8")
|
||||
try:
|
||||
yield rid
|
||||
finally:
|
||||
path.unlink(missing_ok=True)
|
||||
|
||||
|
||||
async def test_manage_research_read_returns_report_text(saved_report):
|
||||
res = await do_manage_research(json.dumps({"action": "read", "id": saved_report}))
|
||||
out = res.get("output", "")
|
||||
# The agent must get the actual report body (not HTML, not an error).
|
||||
assert "Geometry Nodes tutorials are trending" in out
|
||||
assert "trending blender video ideas" in out
|
||||
assert res.get("exit_code") == 0
|
||||
|
||||
|
||||
async def test_panel_launched_rp_id_is_valid_for_read(saved_report):
|
||||
# rp-* ids (panel-launched research) contain a hyphen; the read path's id
|
||||
# guard must accept them, not reject them as invalid.
|
||||
res = await do_manage_research(json.dumps({"action": "read", "id": saved_report}))
|
||||
assert "error" not in res, res
|
||||
|
||||
|
||||
def test_instructions_route_report_reads_to_manage_research():
|
||||
desc = TOOL_SECTIONS["manage_research"]
|
||||
# Steers to the read tool for a finished report...
|
||||
assert "read that report" in desc.lower() or "that report" in desc.lower()
|
||||
assert "action:list" in desc or "action: list" in desc
|
||||
# ...and explicitly away from fetching the HTML report endpoint.
|
||||
assert "/api/research/report/" in desc
|
||||
assert "web_fetch" in desc.lower() or "app_api" in desc.lower()
|
||||
Reference in New Issue
Block a user