preserve web tools in compound artifact workflows

This commit is contained in:
pewdiepie-archdaemon
2026-09-18 01:22:04 +00:00
parent 687b8aa0e6
commit 727ab12e5c
4 changed files with 79 additions and 2 deletions
+5
View File
@@ -10448,6 +10448,11 @@ def _classify_agent_request(messages: List[Dict], last_user: str) -> Dict[str, o
or (_explicit_local_input and not _explicit_web_retrieval)
):
domains.add("web")
if has(
r"\b(?:reviews?|ratings?|testimonials?|評判|レビュー)\b",
r"\b(?:worth|recommend(?:ed|ation)?|pros?\s+and\s+cons?|buying\s+guide)\b",
):
domains.add("web")
if _looks_like_explicit_browser_interaction(retrieval_query) and not (
_personal_domain_turn and not _strong_web_target
):
+51 -2
View File
@@ -699,6 +699,27 @@ def selected_tools_for_request(message: str) -> frozenset[str] | None:
)
):
explicitly_named_web.add("web_fetch")
if (
re.search(r"(?:file://)?/(?:tmp_)?workspace(?:/|\b)", raw_text, re.I)
and re.search(
r"\b(?:build|create|edit|persist|produce|save|write)\b",
raw_text,
re.I,
)
and re.search(
r"\b(?:artifacts?|director(?:y|ies)|files?|outputs?|results?)\b|"
r"\.(?:csv|html|json|jsonl|md|tex|txt)\b",
raw_text,
re.I,
)
):
# Explicit native Web names seal selection to the named tools.
# Compound autonomous jobs also require a bounded local
# read/write/verify surface; without it, requiring shell_files
# makes the whole contract fail closed and drops the Web tools.
explicitly_named_web.update(
{"read_file", "write_file", "edit_file", "python"}
)
return frozenset(explicitly_named_web)
if (
re.search(r"\b(?:look\s*up|search|find)\b", text, re.I)
@@ -718,6 +739,21 @@ def selected_tools_for_request(message: str) -> frozenset[str] | None:
# begin on an arbitrary browser page can ground an answer in stale or
# unrelated content without ever establishing a current source set.
return frozenset({"web_search"})
if re.search(
r"\b(?:reviews?|ratings?|評判|レビュー|testimonials?)\b",
text,
re.I,
) and re.search(
r"\b(?:what(?:'s|\s+is)|how\s+are|which|best|good|bad|worth|recommend|"
r"compare|pros?|cons?|opinions?|thoughts?|about)\b",
text,
re.I,
):
# Product/service review requests are current public-web lookups even
# when the user does not say "search". Route them to web_search before
# the model sees a schema; otherwise a no-tool contract invites raw
# provider-specific markup (notably DeepSeek DSML) that cannot execute.
return frozenset({"web_search"})
if re.search(
r"\buse\s+(?:the\s+)?(?:odysseus\s+)?web_search\b",
raw_text,
@@ -3371,6 +3407,12 @@ def required_read_operation_for_request(message: str, history: Iterable = ()) ->
re.search(r"\b(?:saved\s+)?memor(?:y|ies|es)\b", text, re.I)
and re.search(r"\b(?:pull\s+up|peek|list|show|saved)\b", text, re.I)
and not re.search(r"\b(?:add|edit|change|delete|forget)\b", text, re.I)
and not re.search(
r"\b(?:never|without)\s+(?:(?:using|relying\s+on)\s+)?(?:my\s+)?memory\b|"
r"\bdo\s+not\s+(?:use|rely\s+on)\s+(?:my\s+)?memory\b",
text,
re.I,
)
):
return RequiredReadOperation("manage_memory", {"action": "list"}, maximum)
if (
@@ -4073,8 +4115,15 @@ def requested_capabilities(message: str, history: Iterable = (), *, active_docum
# Explicit native-tool requests are stronger than incidental domain
# words in the research subject (for example, Git ``pull`` must not
# route to scheduled tasks). Keep the whole read-only web family so a
# weak search can recover through fetch/browser without schema growth.
return frozenset({"search_browser"})
# weak search can recover through fetch/browser. A compound artifact
# workflow may also have been deliberately selected with a bounded
# workspace tool surface; preserve that independent family.
selected = selected_tools_for_request(raw_text)
selected_families = (
frozenset().union(*(_families_for_tool(tool) for tool in selected))
if selected else frozenset()
)
return selected_families or frozenset({"search_browser"})
if (
re.search(r"\b(?:latest|recent|current|today(?:'s)?)\b", text, re.I)
and re.search(r"\b(?:info(?:rmation)?|news|nees|updates?)\b", text, re.I)
+10
View File
@@ -192,6 +192,16 @@ def test_typo_heavy_product_problem_is_complete_not_ambiguous_fragment() -> None
assert not _is_ambiguous_short_low_signal(text)
def test_product_review_request_routes_to_web_search_without_search_verb() -> None:
from src.turn_contract import selected_tools_for_request
assert selected_tools_for_request("What's Dyson pencil vac reviews") == frozenset({"web_search"})
assert "web" in _classify_agent_request(
[{"role": "user", "content": "What's Dyson pencil vac reviews"}],
"What's Dyson pencil vac reviews",
)["domains"]
def test_standalone_link_fragment_gets_clarification_path() -> None:
from pathlib import Path
+13
View File
@@ -2267,6 +2267,19 @@ def test_explicit_native_web_workflow_outranks_incidental_task_words():
assert selected_tools_for_request(message) == {"web_search", "web_fetch"}
def test_explicit_native_web_workflow_preserves_workspace_artifact_tools():
message = (
"Use Odysseus web_search to locate each RFC, then web_fetch every page. "
"Create /tmp_workspace/results/inventory.jsonl, read the local inputs, "
"and run the Python validator before finishing."
)
selected = selected_tools_for_request(message)
assert selected == {
"web_search", "web_fetch", "read_file", "write_file", "edit_file", "python",
}
assert requested_capabilities(message) == {"search_browser", "shell_files"}
def test_typoed_webhook_inventory_selects_admin_reader():
message = "list my webhoks again"
assert selected_tools_for_request(message) == {"manage_webhooks"}