enforce distinct research refinement

This commit is contained in:
pewdiepie-archdaemon
2026-09-17 19:02:11 +00:00
parent 6121442658
commit e3107a645d
2 changed files with 68 additions and 8 deletions
+46 -8
View File
@@ -1662,6 +1662,10 @@ def normalize_preview_function_args(name, args, *, user_text=''):
else:
normalized_urls.append(item)
args['urls'] = normalized_urls
single_url = str(args.get('url') or '').strip()
if single_url:
args['urls'] = list(dict.fromkeys([single_url, *args['urls']]))
args.pop('url', None)
if canonical(name) == 'bash' and isinstance(args.get('command'), str):
if re.search(r'\bhostname\b', str(user_text or ''), re.I):
args['command'] = re.sub(
@@ -3129,6 +3133,25 @@ def normalized_search_intent(query):
return ' '.join(token for token in tokens if token not in cosmetic)
def repeated_search_refinement(query, prior_intents):
"""Whether a follow-up only changes cosmetic freshness wording."""
temporal = {
'latest', 'recent', 'current', 'currently', 'today', 'week', 'month',
'year', 'daily', 'weekly', 'now', 'new', 'this', 'past',
}
current = set(normalized_search_intent(query).split()) - temporal
if not current:
return False
for prior in prior_intents or ():
previous = set(str(prior or '').split()) - temporal
if current == previous:
return True
union = current | previous
if union and len(current & previous) / len(union) >= 0.8:
return True
return False
def requested_web_source_links(user_text):
return bool(re.search(
r'\b(?:return|give|show|include|provide|cite|find)\b.{0,35}\b(?:source\s+)?links?\b'
@@ -3767,6 +3790,7 @@ async def stream_preview(*, endpoint_url, model, messages, headers, turn_contrac
permanently_suppressed_tools = set()
successful_duplicate_counts = {}
empty_search_intents = {}
successful_search_intents = []
empty_web_search_attempts = 0
successful_web_searches = 0
successful_web_retrievals = 0
@@ -3788,7 +3812,7 @@ async def stream_preview(*, endpoint_url, model, messages, headers, turn_contrac
artifact_write_phase = False
suppression_completion_attempted = False
budget_completion_attempted = False
answer_recovery_attempted = False
answer_recovery_attempts = 0
force_no_tools_next_round = False
force_web_search_next_round = False
force_private_browser_next_round = False
@@ -4046,10 +4070,10 @@ async def stream_preview(*, endpoint_url, model, messages, headers, turn_contrac
break
if (
contentless_final_response(content)
and not answer_recovery_attempted
and answer_recovery_attempts == 0
and round_number < round_limit
):
answer_recovery_attempted = True
answer_recovery_attempts += 1
force_no_tools_next_round = True
replace_streamed_draft_on_finish = True
history.pop()
@@ -4088,21 +4112,22 @@ async def stream_preview(*, endpoint_url, model, messages, headers, turn_contrac
if (
successful_web_searches
and incomplete_broad_web_answer(content, direct_user_text)
and not answer_recovery_attempted
and answer_recovery_attempts < 2
and round_number < round_limit
):
answer_recovery_attempted = True
answer_recovery_attempts += 1
force_no_tools_next_round = True
replace_streamed_draft_on_finish = True
history.pop()
history.append({
'role': 'user', '_harness_control': True,
'content': (
'Completion check: the draft is only a fragment and does not '
'Completion check: the draft is still too shallow and does not '
'answer the broad current-information request. Using the Web '
'evidence already gathered, provide a complete useful briefing '
'with the main findings, source attribution, and any evidence '
'limitations. Do not call another tool.'
'of at least several substantive paragraphs or equivalent bullets, '
'with the main findings, context, source links, and any evidence '
'limitations. Do not call another tool or return another one-sentence summary.'
),
})
yield event({
@@ -4409,6 +4434,16 @@ async def stream_preview(*, endpoint_url, model, messages, headers, turn_contrac
)
if tool_type == 'web_search':
search_intent = normalized_search_intent(args.get('query'))
if repeated_search_refinement(
args.get('query'), successful_search_intents,
):
force_web_search_next_round = True
calls += 1
raise ValueError(
'This follow-up search is equivalent to an earlier successful '
'query. Change the angle, missing subtopic, source type, or '
'corroboration target instead of only changing freshness wording.'
)
if search_intent and empty_search_intents.get(search_intent, 0) >= 2:
calls += 1
raise ValueError(
@@ -4748,6 +4783,9 @@ async def stream_preview(*, endpoint_url, model, messages, headers, turn_contrac
})
if not failed and canonical(actual_tool) == 'web_search':
successful_web_searches += 1
successful_intent = normalized_search_intent(args.get('query'))
if successful_intent:
successful_search_intents.append(successful_intent)
if successful_web_searches == 2 and not required_artifacts:
round_recovery_messages.append(
'Research discovery is complete after two searches. Do not search '
+22
View File
@@ -1864,6 +1864,28 @@ def test_broad_current_web_request_covers_natural_phrasings(prompt):
assert broad_current_web_request(prompt)
def test_followup_search_must_change_subject_angle_not_only_freshness():
from src.clean_agent_preview import repeated_search_refinement
assert repeated_search_refinement('latest AI news this week', ['ai news'])
assert repeated_search_refinement('current Sweden events', ['sweden events'])
assert not repeated_search_refinement(
'Sweden election coalition negotiations', ['sweden current events']
)
def test_web_fetch_collapses_single_and_batch_url_fields_without_losing_targets():
tool, args = normalize_preview_function_args('web_fetch', {
'url': 'https://example.org/a',
'urls': ['https://example.org/a', 'https://example.org/b'],
})
assert tool == 'web_fetch'
assert args == {
'urls': ['https://example.org/a', 'https://example.org/b'],
}
def test_preview_allows_only_reversible_client_local_ui_control():
assert preview_call_allowed(
'ui_control', {'action': 'open_panel', 'name': 'gallery'}, 'open gallery'