phase: 94_ls_tree_drilldown
All green. Verification complete. **Phase 94 — `ls` drill-down tree: final verification pass (all 5 tasks were already complete; verified, nothing to fix)** - Verified `ls` 3-level tree (`app/rag/agent.py`): `ls()` sources + summaries, `ls(source)`/`ls(source/folder)` drill-down, 50-line file cap + grep-pointer note, NOT-A-FOLDER teaching refusal - Verified `folder_summaries` (migration 0017, model, `app/rag/folder_summaries.py` generator: `FOLDER_SUMMARY_MODE` marker, fail-soft per folder, ≥2-doc scope + prune) wired change-gated in both sync paths - Verified 10-turn fixture battery verdict recorded in `TOOL_CALLING_TESTING.md` §9 (2026-09-11): turbo PASS 19/19 contract, 98.7 s (−12.5…−13.2 % vs baseline); lite PASS 18/18, 43.6 s (+7.7 %) — accuracy at/above baseline, gate met - `uv run pytest --cov=app --cov-report=term-missing` → 1939 passed, 0 failed; TOTAL coverage **99 %** (folder_summaries.py 100 %) - `uv run ruff check .` → clean; `uv run pyright` → 0 errors, 0 warnings - E2E in isolation: `test_ls_tree_drilldown.py` 3 passed; `test_agent_document_tools` 4, `test_agent_unlimited_tools` 4, `test_harness_aligned_tools` 3, `test_search_tool` 3, `test_grep_regex_teaching` 2, `test_response_to_docs` 4 — all passed (read/grep contracts untouched) - Dedicated folder-summary tests (fail-soft, prune, both sync paths, migration): 46 passed - Completion criteria: all 6 met; working tree holds only phase-94 changes (commit left to harness per protocol) **Next pending phase:** `95_read_truncation_cap`
This commit is contained in:
+31
-1
@@ -41,7 +41,16 @@ decisions):
|
||||
(pruning covers the union; the CLI's no-prune default is unchanged);
|
||||
5. when the import changed the KB (added + updated > 0),
|
||||
``regenerate_overview`` refreshes the single ``kb_overview`` row
|
||||
(phase 31 trigger, best-effort inside);
|
||||
(phase 31 trigger, best-effort inside) — and ``generate_
|
||||
folder_summaries`` (phase 94, task 02) regenerates the stored folder
|
||||
summaries (the drill-down ``ls``'s per-level descriptions): its gate
|
||||
is the same change trigger **plus** an empty ``folder_summaries``
|
||||
table (the first sync after migration 0017 — the KB may predate the
|
||||
table). It is per-folder fail-soft (a ``lite`` outage keeps the
|
||||
failed folders' previous rows and never flips the run to
|
||||
``failed``) and only flushes — this run's own short-lived session
|
||||
commits (the phase-53 convention), so a folder failure never blocks
|
||||
step 6's bump;
|
||||
6. when the import changed the KB (added + updated + pruned > 0 — the
|
||||
saved-chat invalidation gate, phase 53 task 02: a pruned document
|
||||
can invalidate a saved answer that cited it, deliberately broader
|
||||
@@ -79,6 +88,7 @@ from app.config import get_settings
|
||||
from app.core.auth import require_admin
|
||||
from app.core.errors import sanitize_error as _sanitize_error
|
||||
from app.db import SessionLocal
|
||||
from app.rag.folder_summaries import folder_summary_table_empty, generate_folder_summaries
|
||||
from app.rag.git_sources import effective_sources
|
||||
from app.rag.importer import ImportSummary, import_sources
|
||||
from app.rag.llm import LLMClient, check_models
|
||||
@@ -251,6 +261,26 @@ async def _run_sync() -> None:
|
||||
overview = False
|
||||
if summary.added + summary.updated > 0:
|
||||
overview = await regenerate_overview(llm)
|
||||
# Phase 94 (task 02): the folder summaries — the drill-down
|
||||
# ls's per-level descriptions. Same change gate as the overview
|
||||
# (added + updated > 0), plus the table-empty first-run trigger
|
||||
# (the first sync after migration 0017 — the KB may have been
|
||||
# imported by the CLI before the table landed). The generator is
|
||||
# per-folder fail-soft (a lite outage never flips the run to
|
||||
# failed) and only flushes: this run's own short-lived session
|
||||
# commits (the phase-53 convention), so the step-6 bump stays
|
||||
# change-gated on the KB, not on the summaries. No status-surface
|
||||
# change: the stats are log-only (the detail shape is untouched).
|
||||
fs_db = SessionLocal()
|
||||
try:
|
||||
if summary.added + summary.updated > 0 or folder_summary_table_empty(fs_db):
|
||||
folder_stats = await generate_folder_summaries(fs_db, llm)
|
||||
fs_db.commit()
|
||||
logger.info("sync: folder_summaries stats=%s", folder_stats)
|
||||
else:
|
||||
logger.info("sync: folder_summaries skipped (KB unchanged)")
|
||||
finally:
|
||||
fs_db.close()
|
||||
# Phase 53 (task 02): a sync that changed the KB advances the
|
||||
# sources version exactly once — the saved-chat invalidation
|
||||
# marker (task 03 stamps rows against it). The gate is
|
||||
|
||||
Reference in New Issue
Block a user