feat(agent): align the document tools with the harness-trained shape — ls, read(path), grep(pattern, path?)
This commit is contained in:
@@ -1,4 +1,6 @@
|
||||
"""Phase 68 E2E (Playwright, mock-only): the ``search_documents`` tool.
|
||||
"""Phase 68 E2E (Playwright, mock-only): the ``grep`` tool (the
|
||||
phase-68 search tool, renamed to the harness-aligned ``grep`` in
|
||||
phase 70; the A5 match/output contract is unchanged).
|
||||
|
||||
Story: n/a (TODO-derived — the owner roadmap confirmation 2026-09-01,
|
||||
TODO.md L4: "Add a search tool that allows the LLM to grep through the
|
||||
@@ -14,8 +16,8 @@ message contains ``search your documents`` (``SEARCH_TRIGGER``)
|
||||
prompt):
|
||||
|
||||
1. request 1 (``tools`` offered, no search result yet) → streams ONLY
|
||||
``tool_calls`` deltas calling ``search_documents`` with
|
||||
``{"pattern": SEARCH_PATTERN}`` (id ``call_0``);
|
||||
``tool_calls`` deltas calling ``grep`` with ``{"pattern":
|
||||
SEARCH_PATTERN}`` (id ``call_0``);
|
||||
2. request 2 (a ``tool``-role search result — the
|
||||
``source/path:line: text`` match line) → the content answer
|
||||
``Found <first matched line's content up to 80 chars>`` — so this
|
||||
@@ -40,13 +42,13 @@ shadow the phase-37/45 flows and vice versa).
|
||||
|
||||
Test → phase mapping:
|
||||
1. ``test_search_flow_searches_and_answers_from_match`` — the live
|
||||
search flow: the SSE carries the ``tool`` frame
|
||||
(``search_documents`` with ``argument = <sentinel>``, ahead of any
|
||||
delta), #send-status recorded the transient "… is searching for
|
||||
<sentinel>" state, the bubble shows ONE ``🔎 Searching for``
|
||||
tool line with the sentinel in a ``<code>`` element, the answer
|
||||
quotes the matched line (``Found …`` — the match reached the
|
||||
model), and the turn settles to idle with no error banner.
|
||||
search flow: the SSE carries the ``tool`` frame (``grep`` with
|
||||
``argument = <sentinel>``, ahead of any delta), #send-status
|
||||
recorded the transient "… is searching for <sentinel>" state, the
|
||||
bubble shows ONE ``🔎 Searching for`` tool line with the sentinel in
|
||||
a ``<code>`` element, the answer quotes the matched line
|
||||
(``Found …`` — the match reached the model), and the turn settles to
|
||||
idle with no error banner.
|
||||
2. ``test_search_adds_no_source_by_itself`` — context accounting
|
||||
(locked A5): the search-only flow (no read) leaves
|
||||
``done.sources`` / the source chips / ``query_log.sources`` at the
|
||||
@@ -367,12 +369,12 @@ def test_search_flow_searches_and_answers_from_match(
|
||||
)
|
||||
assert i_think is not None and i_think < i_search, statuses
|
||||
|
||||
# Wire level: exactly ONE `tool` frame — search_documents carrying
|
||||
# the PATTERN as its argument (phase 68 task 02) — ahead of the
|
||||
# first `delta` frame.
|
||||
# Wire level: exactly ONE `tool` frame — grep carrying the PATTERN
|
||||
# as its argument (phase 68 task 02; phase 70 renamed the tool) —
|
||||
# ahead of the first `delta` frame.
|
||||
frames = _frames(page)
|
||||
assert _tool_frames(frames) == [
|
||||
{"type": "tool", "name": "search_documents", "argument": SEARCH_PATTERN}
|
||||
{"type": "tool", "name": "grep", "argument": SEARCH_PATTERN}
|
||||
]
|
||||
first_delta = next(i for i, f in enumerate(frames) if f.get("type") == "delta")
|
||||
assert all(
|
||||
@@ -424,7 +426,7 @@ def test_search_adds_no_source_by_itself(
|
||||
# baseline: the one fixture doc, nothing added by the search.
|
||||
frames = _frames(page)
|
||||
assert _tool_frames(frames) == [
|
||||
{"type": "tool", "name": "search_documents", "argument": SEARCH_PATTERN}
|
||||
{"type": "tool", "name": "grep", "argument": SEARCH_PATTERN}
|
||||
]
|
||||
done = next(f for f in frames if f.get("type") == "done")
|
||||
assert done["deflected"] is False
|
||||
|
||||
Reference in New Issue
Block a user