Compare commits
2 commits
b2d00dd301
...
896dac686d
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
896dac686d | ||
|
|
8fb2f90678 |
2 changed files with 63 additions and 5 deletions
|
|
@ -756,6 +756,30 @@ def _get_child_summaries(dir_path, cache):
|
||||||
_SURVEY_CONFIDENCE_THRESHOLD = 0.5
|
_SURVEY_CONFIDENCE_THRESHOLD = 0.5
|
||||||
_PROTECTED_DIR_TOOLS = {"submit_report"}
|
_PROTECTED_DIR_TOOLS = {"submit_report"}
|
||||||
|
|
||||||
|
# Survey-skip thresholds. Skip the survey only when BOTH are below.
|
||||||
|
# See #46 for the plan to revisit these with empirical data.
|
||||||
|
_SURVEY_MIN_FILES = 5
|
||||||
|
_SURVEY_MIN_DIRS = 2
|
||||||
|
|
||||||
|
|
||||||
|
def _default_survey():
|
||||||
|
"""Synthetic survey for targets too small to justify the API call.
|
||||||
|
|
||||||
|
confidence=0.0 ensures _filter_dir_tools() never enforces skip_tools
|
||||||
|
based on this synthetic value — the dir loop keeps its full toolbox.
|
||||||
|
"""
|
||||||
|
return {
|
||||||
|
"description": "Small target — survey skipped.",
|
||||||
|
"approach": (
|
||||||
|
"The target is small enough to investigate exhaustively. "
|
||||||
|
"Read every file directly."
|
||||||
|
),
|
||||||
|
"relevant_tools": [],
|
||||||
|
"skip_tools": [],
|
||||||
|
"domain_notes": "",
|
||||||
|
"confidence": 0.0,
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
def _format_survey_block(survey):
|
def _format_survey_block(survey):
|
||||||
"""Render survey output as a labeled text block for the dir prompt."""
|
"""Render survey output as a labeled text block for the dir prompt."""
|
||||||
|
|
@ -1228,6 +1252,19 @@ def _run_investigation(client, target, report, show_hidden=False,
|
||||||
f"{'' if is_new else ' (resumed)'}", file=sys.stderr)
|
f"{'' if is_new else ' (resumed)'}", file=sys.stderr)
|
||||||
print(f" [AI] Cache: {cache.root}/", file=sys.stderr)
|
print(f" [AI] Cache: {cache.root}/", file=sys.stderr)
|
||||||
|
|
||||||
|
all_dirs = _discover_directories(target, show_hidden=show_hidden,
|
||||||
|
exclude=exclude)
|
||||||
|
|
||||||
|
total_files = sum((report.get("file_categories") or {}).values())
|
||||||
|
total_dirs = len(all_dirs)
|
||||||
|
if total_files < _SURVEY_MIN_FILES and total_dirs < _SURVEY_MIN_DIRS:
|
||||||
|
print(
|
||||||
|
f" [AI] Survey skipped — {total_files} files, {total_dirs} dirs "
|
||||||
|
f"(below threshold).",
|
||||||
|
file=sys.stderr,
|
||||||
|
)
|
||||||
|
survey = _default_survey()
|
||||||
|
else:
|
||||||
print(" [AI] Survey pass...", file=sys.stderr)
|
print(" [AI] Survey pass...", file=sys.stderr)
|
||||||
survey = _run_survey(client, target, report, tracker, verbose=verbose)
|
survey = _run_survey(client, target, report, tracker, verbose=verbose)
|
||||||
if survey:
|
if survey:
|
||||||
|
|
@ -1251,9 +1288,6 @@ def _run_investigation(client, target, report, show_hidden=False,
|
||||||
else:
|
else:
|
||||||
print(" [AI] Survey unavailable — proceeding without it.", file=sys.stderr)
|
print(" [AI] Survey unavailable — proceeding without it.", file=sys.stderr)
|
||||||
|
|
||||||
all_dirs = _discover_directories(target, show_hidden=show_hidden,
|
|
||||||
exclude=exclude)
|
|
||||||
|
|
||||||
to_investigate = []
|
to_investigate = []
|
||||||
cached_count = 0
|
cached_count = 0
|
||||||
for d in all_dirs:
|
for d in all_dirs:
|
||||||
|
|
|
||||||
|
|
@ -108,5 +108,29 @@ class FormatSurveyBlockTests(unittest.TestCase):
|
||||||
self.assertNotIn("Skip tools", block)
|
self.assertNotIn("Skip tools", block)
|
||||||
|
|
||||||
|
|
||||||
|
class DefaultSurveyTests(unittest.TestCase):
|
||||||
|
def test_has_all_required_keys(self):
|
||||||
|
survey = ai._default_survey()
|
||||||
|
for key in ("description", "approach", "relevant_tools",
|
||||||
|
"skip_tools", "domain_notes", "confidence"):
|
||||||
|
self.assertIn(key, survey)
|
||||||
|
|
||||||
|
def test_confidence_below_filter_threshold(self):
|
||||||
|
# Must be < _SURVEY_CONFIDENCE_THRESHOLD so _filter_dir_tools()
|
||||||
|
# never enforces skip_tools from a synthetic survey.
|
||||||
|
self.assertLess(
|
||||||
|
ai._default_survey()["confidence"],
|
||||||
|
ai._SURVEY_CONFIDENCE_THRESHOLD,
|
||||||
|
)
|
||||||
|
|
||||||
|
def test_filter_returns_full_toolbox_for_default(self):
|
||||||
|
all_names = {t["name"] for t in ai._DIR_TOOLS}
|
||||||
|
result = {t["name"] for t in ai._filter_dir_tools(ai._default_survey())}
|
||||||
|
self.assertEqual(result, all_names)
|
||||||
|
|
||||||
|
def test_skip_tools_is_empty(self):
|
||||||
|
self.assertEqual(ai._default_survey()["skip_tools"], [])
|
||||||
|
|
||||||
|
|
||||||
if __name__ == "__main__":
|
if __name__ == "__main__":
|
||||||
unittest.main()
|
unittest.main()
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue