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:
+44
-19
@@ -31,7 +31,15 @@ name*, not a directory or file path, and ``read``/``grep`` take the
|
||||
combined ``source/path`` string *including the source name* (a bare
|
||||
document path will not resolve) — the same two things the phase-72
|
||||
teaching refusals in :mod:`app.rag.agent` re-state after the fact, so
|
||||
the model carries the contract before it calls a tool): the **HIGH**
|
||||
the model carries the contract before it calls a tool; phase 94,
|
||||
task 03: the ``ls`` clause is rewritten to the drill-down tree
|
||||
contract — no ``path``: the synced sources with counts + summaries, a
|
||||
source name: its top-level folders + files, a ``source/folder`` path:
|
||||
one level deeper — a listing shows only that level's subfolders + own
|
||||
files (never the whole KB in one call), the folder summaries say
|
||||
what's in a folder before drilling, and ``grep`` stays the locator for
|
||||
finding one document without listing; the ``read``/``grep`` clauses
|
||||
and the discipline rules are byte-identical): the **HIGH**
|
||||
prompt only carries a ``<tools>`` section after the ``<documents>``
|
||||
body — the grounded turn may extend its context through the three
|
||||
server-side tools (round-capped, see :mod:`app.rag.agent`; the cap is
|
||||
@@ -103,7 +111,17 @@ _KB_INTRO = (
|
||||
#: ``path`` is a *source name* (not a directory or file path) and
|
||||
#: ``read``/``grep`` take the combined ``source/path`` string *including
|
||||
#: the source name* (a bare document path will not resolve) — the same
|
||||
#: two things the phase-72 teaching refusals re-state after the fact):
|
||||
#: two things the phase-72 teaching refusals re-state after the fact;
|
||||
#: phase 94, task 03 — the owner-permitted tool-surface revision,
|
||||
#: recorded in the phase 94 overview: the ``ls`` clause is rewritten
|
||||
#: to the drill-down tree contract — no ``path``: the synced sources
|
||||
#: with counts + summaries, a source name: its top-level folders +
|
||||
#: files, a ``source/folder`` path: one level deeper — a listing shows
|
||||
#: only that level's subfolders + own files, never the whole KB in one
|
||||
#: call, the folder summaries say what's in a folder before drilling,
|
||||
#: and ``grep`` stays the locator for finding one document without
|
||||
#: listing; the ``read``/``grep`` clauses and the discipline rules are
|
||||
#: byte-identical):
|
||||
#: a grounded turn may extend its context through the three server-side
|
||||
#: tools (round cap: ``BOR_AGENT_MAX_ROUNDS`` — the cap is the bound and
|
||||
#: this section does not re-state it, phase 45). Appended after the mode
|
||||
@@ -139,23 +157,30 @@ _KB_INTRO = (
|
||||
TOOLS_SECTION: str = (
|
||||
"<tools>\n"
|
||||
"You may extend your context with three tools. `ls` lists the "
|
||||
"indexed documents as `source: X | path: Y | title: Z` lines; its "
|
||||
"optional `path` argument is a source name (e.g. 'homelab'), not a "
|
||||
"directory or file path — omit it to list every document. `read` "
|
||||
"pulls in one document by its combined `source/path` string, "
|
||||
"exactly as shown in the `ls` output — including the source name — "
|
||||
"adding its full content to your context. Do not call `read` for a "
|
||||
"document already shown in the <documents> section, even when the "
|
||||
"user asks you to open or read it — its full text is already in "
|
||||
"your prompt; answer directly from it. For `read`, a bare document "
|
||||
"path (without the source name) will not resolve. `grep` locates an "
|
||||
"exact string (case-insensitive) in the indexed documents and "
|
||||
"returns up to 20 matching `source/path:line: text` lines — a "
|
||||
"locator, not a context-adder: read the winner with `read`. A grep "
|
||||
"pattern is a plain substring, NEVER a regex — '.*' and '\\.' are "
|
||||
"literal text there; if such a pattern returns no matches, retry "
|
||||
"with the plain text you expect to see. For a normal search pass "
|
||||
"only `pattern` — its optional `path` argument "
|
||||
"knowledge base as a tree, one level at a time: with no `path` it "
|
||||
"lists every synced source with its document count and a summary "
|
||||
"of its contents; with a source name (e.g. 'homelab') it lists "
|
||||
"that source's top-level folders and files; with a `source/folder` "
|
||||
"path it drills one level deeper. A listing shows only that "
|
||||
"level's subfolders and its own files — never the whole knowledge "
|
||||
"base in one call — and each folder line's summary says what the "
|
||||
"folder contains before you drill into it. File lines are "
|
||||
"`source: X | path: Y | title: Z`; to find one specific document "
|
||||
"without listing, use `grep`. `read` pulls in one document by its "
|
||||
"combined `source/path` string, exactly as shown in the `ls` "
|
||||
"output — including the source name — adding its full content to "
|
||||
"your context. Do not call `read` for a document already shown in "
|
||||
"the <documents> section, even when the user asks you to open or "
|
||||
"read it — its full text is already in your prompt; answer "
|
||||
"directly from it. For `read`, a bare document path (without the "
|
||||
"source name) will not resolve. `grep` locates an exact string "
|
||||
"(case-insensitive) in the indexed documents and returns up to 20 "
|
||||
"matching `source/path:line: text` lines — a locator, not a "
|
||||
"context-adder: read the winner with `read`. A grep pattern is a "
|
||||
"plain substring, NEVER a regex — '.*' and '\\.' are literal text "
|
||||
"there; if such a pattern returns no matches, retry with the plain "
|
||||
"text you expect to see. For a normal search pass only `pattern` — "
|
||||
"its optional `path` argument "
|
||||
"limits the search to one document you already know, by the same "
|
||||
"combined `source/path` string; never a source name — a bare "
|
||||
"document path (without the source name) will not resolve there "
|
||||
|
||||
Reference in New Issue
Block a user