@@ -15728,6 +15728,7 @@ def result_requires_message_reload(result: Any) -> bool:
1572815728 history_grounded_search_used = False
1572915729 history_only_answerability = None
1573015730 prior_grounded_document_refs = []
15731+ prior_grounded_source_merge = None
1573115732 continuity_decision = None
1573215733 effective_document_scope = document_scope
1573315734 effective_selected_document_ids = list(selected_document_ids or [])
@@ -16067,6 +16068,67 @@ def result_requires_message_reload(result: Any) -> bool:
1606716068 selected_document_id = effective_selected_document_id
1606816069 document_scope = effective_document_scope
1606916070
16071+ prior_grounded_document_refs = _normalize_prior_grounded_document_refs(conversation_item)
16072+ current_document_context_available = bool(
16073+ effective_selected_document_ids
16074+ or effective_selected_document_id
16075+ or hybrid_search_enabled
16076+ or document_context_requested
16077+ )
16078+ if (
16079+ current_document_context_available
16080+ and prior_grounded_document_refs
16081+ and _prior_grounded_source_reference_requested(user_message)
16082+ ):
16083+ prior_search_parameters = build_prior_grounded_document_search_parameters(
16084+ prior_grounded_document_refs
16085+ )
16086+ prior_search_parameters = revalidate_prior_grounded_document_search_parameters(
16087+ user_id,
16088+ prior_search_parameters,
16089+ )
16090+ prior_grounded_source_merge = _merge_prior_grounded_sources_with_current_context(
16091+ effective_selected_document_ids,
16092+ effective_document_scope,
16093+ effective_active_group_ids,
16094+ effective_active_public_workspace_ids,
16095+ prior_search_parameters,
16096+ )
16097+ if prior_grounded_source_merge.get('used'):
16098+ effective_selected_document_ids = list(
16099+ prior_grounded_source_merge.get('document_ids') or []
16100+ )
16101+ effective_selected_document_id = (
16102+ effective_selected_document_ids[0]
16103+ if len(effective_selected_document_ids) == 1
16104+ else None
16105+ )
16106+ effective_document_scope = prior_grounded_source_merge.get('doc_scope') or 'all'
16107+ effective_active_group_ids = list(
16108+ prior_grounded_source_merge.get('active_group_ids') or []
16109+ )
16110+ effective_active_group_id = (
16111+ effective_active_group_ids[0]
16112+ if effective_active_group_ids
16113+ else None
16114+ )
16115+ effective_active_public_workspace_ids = list(
16116+ prior_grounded_source_merge.get('active_public_workspace_ids') or []
16117+ )
16118+ effective_active_public_workspace_id = (
16119+ effective_active_public_workspace_ids[0]
16120+ if effective_active_public_workspace_ids
16121+ else None
16122+ )
16123+ selected_document_ids = list(effective_selected_document_ids)
16124+ selected_document_id = effective_selected_document_id
16125+ document_scope = effective_document_scope
16126+ active_group_ids = list(effective_active_group_ids)
16127+ active_group_id = effective_active_group_id
16128+ active_public_workspace_ids = list(effective_active_public_workspace_ids)
16129+ active_public_workspace_id = effective_active_public_workspace_id
16130+ hybrid_search_enabled = True
16131+
1607016132 mixed_source_manifest = []
1607116133 mixed_source_partitions = {}
1607216134 mixed_source_narrative_document_ids = []
@@ -16274,6 +16336,13 @@ def result_requires_message_reload(result: Any) -> bool:
1627416336 'tags': tags_filter,
1627516337 'classification': classifications_to_send
1627616338 }
16339+ if prior_grounded_source_merge:
16340+ user_metadata['workspace_search']['prior_grounded_source_merge'] = {
16341+ 'used': bool(prior_grounded_source_merge.get('used')),
16342+ 'prior_document_count': len(prior_grounded_source_merge.get('prior_document_ids') or []),
16343+ 'added_document_count': len(prior_grounded_source_merge.get('prior_added_document_ids') or []),
16344+ 'selection_origin': 'selected+history',
16345+ }
1627716346 if assigned_knowledge_filters:
1627816347 assigned_knowledge = assigned_knowledge_filters.get('assigned_knowledge') or {}
1627916348 user_metadata['workspace_search']['assigned_knowledge'] = {
@@ -16599,8 +16668,8 @@ def result_requires_message_reload(result: Any) -> bool:
1659916668 not original_hybrid_search_enabled
1660016669 and not explicit_external_retrieval_requested
1660116670 and not mixed_source_explicit_selection
16671+ and not prior_grounded_source_merge
1660216672 ):
16603- prior_grounded_document_refs = _normalize_prior_grounded_document_refs(conversation_item)
1660416673 if prior_grounded_document_refs:
1660516674 continuity_decision = _resolve_reauthorized_continuity_decision(
1660616675 settings,
@@ -18283,6 +18352,7 @@ def record_tabular_post_processing_thought(thought_payload):
1828318352 current_document_context_requested=(
1828418353 is_mixed_source_chat_search_enabled(settings)
1828518354 and document_context_requested
18355+ or bool(prior_grounded_source_merge)
1828618356 ),
1828718357 ):
1828818358 history_grounding_message = build_history_grounding_system_message()
@@ -19971,6 +20041,7 @@ def stream_cancel_requested():
1997120041 history_grounded_search_used = False
1997220042 history_only_answerability = None
1997320043 prior_grounded_document_refs = []
20044+ prior_grounded_source_merge = None
1997420045 continuity_decision = None
1997520046 effective_document_scope = document_scope
1997620047 effective_selected_document_ids = list(selected_document_ids or [])
@@ -20330,6 +20401,67 @@ def build_streaming_capability_usage():
2033020401 selected_document_id = effective_selected_document_id
2033120402 document_scope = effective_document_scope
2033220403
20404+ prior_grounded_document_refs = _normalize_prior_grounded_document_refs(conversation_item)
20405+ current_document_context_available = bool(
20406+ effective_selected_document_ids
20407+ or effective_selected_document_id
20408+ or hybrid_search_enabled
20409+ or document_context_requested
20410+ )
20411+ if (
20412+ current_document_context_available
20413+ and prior_grounded_document_refs
20414+ and _prior_grounded_source_reference_requested(user_message)
20415+ ):
20416+ prior_search_parameters = build_prior_grounded_document_search_parameters(
20417+ prior_grounded_document_refs
20418+ )
20419+ prior_search_parameters = revalidate_prior_grounded_document_search_parameters(
20420+ user_id,
20421+ prior_search_parameters,
20422+ )
20423+ prior_grounded_source_merge = _merge_prior_grounded_sources_with_current_context(
20424+ effective_selected_document_ids,
20425+ effective_document_scope,
20426+ effective_active_group_ids,
20427+ effective_active_public_workspace_ids,
20428+ prior_search_parameters,
20429+ )
20430+ if prior_grounded_source_merge.get('used'):
20431+ effective_selected_document_ids = list(
20432+ prior_grounded_source_merge.get('document_ids') or []
20433+ )
20434+ effective_selected_document_id = (
20435+ effective_selected_document_ids[0]
20436+ if len(effective_selected_document_ids) == 1
20437+ else None
20438+ )
20439+ effective_document_scope = prior_grounded_source_merge.get('doc_scope') or 'all'
20440+ effective_active_group_ids = list(
20441+ prior_grounded_source_merge.get('active_group_ids') or []
20442+ )
20443+ effective_active_group_id = (
20444+ effective_active_group_ids[0]
20445+ if effective_active_group_ids
20446+ else None
20447+ )
20448+ effective_active_public_workspace_ids = list(
20449+ prior_grounded_source_merge.get('active_public_workspace_ids') or []
20450+ )
20451+ effective_active_public_workspace_id = (
20452+ effective_active_public_workspace_ids[0]
20453+ if effective_active_public_workspace_ids
20454+ else None
20455+ )
20456+ selected_document_ids = list(effective_selected_document_ids)
20457+ selected_document_id = effective_selected_document_id
20458+ document_scope = effective_document_scope
20459+ active_group_ids = list(effective_active_group_ids)
20460+ active_group_id = effective_active_group_id
20461+ active_public_workspace_ids = list(effective_active_public_workspace_ids)
20462+ active_public_workspace_id = effective_active_public_workspace_id
20463+ hybrid_search_enabled = True
20464+
2033320465 mixed_source_manifest = []
2033420466 mixed_source_partitions = {}
2033520467 mixed_source_narrative_document_ids = []
@@ -20527,6 +20659,13 @@ def build_streaming_capability_usage():
2052720659 'active_public_workspace_ids': effective_active_public_workspace_ids,
2052820660 'classification': classifications_to_send
2052920661 }
20662+ if prior_grounded_source_merge:
20663+ user_metadata['workspace_search']['prior_grounded_source_merge'] = {
20664+ 'used': bool(prior_grounded_source_merge.get('used')),
20665+ 'prior_document_count': len(prior_grounded_source_merge.get('prior_document_ids') or []),
20666+ 'added_document_count': len(prior_grounded_source_merge.get('prior_added_document_ids') or []),
20667+ 'selection_origin': 'selected+history',
20668+ }
2053020669 if assigned_knowledge_filters:
2053120670 assigned_knowledge = assigned_knowledge_filters.get('assigned_knowledge') or {}
2053220671 user_metadata['workspace_search']['assigned_knowledge'] = {
@@ -20872,8 +21011,8 @@ def record_and_publish_streaming_thought(thought_payload):
2087221011 not original_hybrid_search_enabled
2087321012 and not explicit_external_retrieval_requested
2087421013 and not mixed_source_explicit_selection
21014+ and not prior_grounded_source_merge
2087521015 ):
20876- prior_grounded_document_refs = _normalize_prior_grounded_document_refs(conversation_item)
2087721016 if prior_grounded_document_refs:
2087821017 continuity_decision = _resolve_reauthorized_continuity_decision(
2087921018 settings,
@@ -22170,6 +22309,7 @@ def record_and_publish_streaming_thought(thought_payload):
2217022309 current_document_context_requested=(
2217122310 is_mixed_source_chat_search_enabled(settings)
2217222311 and document_context_requested
22312+ or bool(prior_grounded_source_merge)
2217322313 ),
2217422314 ):
2217522315 history_grounding_message = build_history_grounding_system_message()
@@ -24246,6 +24386,82 @@ def revalidate_prior_grounded_document_search_parameters(user_id, search_paramet
2424624386 return normalized_parameters
2424724387
2424824388
24389+ def _prior_grounded_source_reference_requested(user_message):
24390+ """Return whether the user is asking to reuse a prior grounded source."""
24391+ normalized_message = re.sub(r'\s+', ' ', str(user_message or '').strip().casefold())
24392+ if not normalized_message:
24393+ return False
24394+
24395+ source_noun_pattern = (
24396+ r'(?:source|document|file|template|spreadsheet|workbook|table|xml|json|pdf|csv|xlsx|xls)'
24397+ )
24398+ reference_patterns = (
24399+ rf'\b(?:that|those|same|previous|prior|earlier|last)\s+{source_noun_pattern}\b',
24400+ rf'\b(?:that|the|same|previous|prior|earlier|last)\s+'
24401+ rf'(?:xml|json|pdf|csv|xlsx|xls)\s+(?:source|document|file|template|workbook)\b',
24402+ rf'\b(?:into|in|with|using|from|against|compare\s+to)\s+'
24403+ rf'(?:that|the|same|previous|prior|earlier|last)\s+{source_noun_pattern}\b',
24404+ )
24405+ return any(re.search(pattern, normalized_message) for pattern in reference_patterns)
24406+
24407+
24408+ def _merge_unique_strings(*collections):
24409+ merged = []
24410+ seen_values = set()
24411+ for collection in collections:
24412+ for value in list(collection or []):
24413+ normalized_value = str(value or '').strip()
24414+ if not normalized_value or normalized_value in seen_values:
24415+ continue
24416+ seen_values.add(normalized_value)
24417+ merged.append(normalized_value)
24418+ return merged
24419+
24420+
24421+ def _merge_prior_grounded_sources_with_current_context(
24422+ current_document_ids,
24423+ current_document_scope,
24424+ current_active_group_ids,
24425+ current_active_public_workspace_ids,
24426+ prior_search_parameters,
24427+ ):
24428+ """Merge reauthorized prior grounded source parameters into current source context."""
24429+ prior_document_ids = _normalize_conversation_task_document_ids(
24430+ (prior_search_parameters or {}).get('document_ids')
24431+ )
24432+ current_document_ids = _normalize_conversation_task_document_ids(current_document_ids)
24433+ current_document_id_set = set(current_document_ids)
24434+ prior_only_document_ids = [
24435+ document_id
24436+ for document_id in prior_document_ids
24437+ if document_id not in current_document_id_set
24438+ ]
24439+ merged_document_ids = _merge_unique_strings(current_document_ids, prior_document_ids)
24440+
24441+ current_scope = str(current_document_scope or '').strip().lower()
24442+ prior_scope = str((prior_search_parameters or {}).get('doc_scope') or '').strip().lower()
24443+ scope_candidates = [scope for scope in (current_scope, prior_scope) if scope]
24444+ merged_scope = scope_candidates[0] if len(set(scope_candidates)) == 1 else 'all'
24445+ if not scope_candidates:
24446+ merged_scope = None
24447+
24448+ return {
24449+ 'used': bool(prior_only_document_ids),
24450+ 'document_ids': merged_document_ids,
24451+ 'prior_document_ids': prior_document_ids,
24452+ 'prior_added_document_ids': prior_only_document_ids,
24453+ 'doc_scope': merged_scope,
24454+ 'active_group_ids': _merge_unique_strings(
24455+ current_active_group_ids,
24456+ (prior_search_parameters or {}).get('active_group_ids'),
24457+ ),
24458+ 'active_public_workspace_ids': _merge_unique_strings(
24459+ current_active_public_workspace_ids,
24460+ (prior_search_parameters or {}).get('active_public_workspace_ids'),
24461+ ),
24462+ }
24463+
24464+
2424924465def build_history_only_assessment_messages(history_segments, default_system_prompt=''):
2425024466 """Construct the prompt context used to decide whether history alone is sufficient."""
2425124467 assessment_messages = []
0 commit comments