@@ -53,17 +53,18 @@ def _parse_citations(text: str) -> list[tuple[str, _ParsedCitation | None]]:
5353
5454 has_url = url is not None
5555 has_reference = reference is not None
56+ has_page_number = page_number is not None
5657
5758 if has_url and not has_reference :
5859 # web citation
5960 citation = _ParsedCitation (title = title , url = url , page_number = page_number )
60- elif has_reference and not has_url :
61+ elif has_reference and has_page_number and not has_url :
6162 # context grounding citation
6263 citation = _ParsedCitation (
6364 title = title , reference = reference , page_number = page_number
6465 )
6566 else :
66- # skip; citation has no url= or reference=
67+ # skip; doesn't match a valid source type
6768 if preceding_text :
6869 segments .append ((preceding_text , None ))
6970 cursor = match .end ()
@@ -90,30 +91,32 @@ def _make_source(
9091 source_numbers : dict [_ParsedCitation , int ],
9192 next_number : int ,
9293) -> tuple [
93- UiPathConversationCitationSourceUrl | UiPathConversationCitationSourceMedia , int
94+ UiPathConversationCitationSourceUrl | UiPathConversationCitationSourceMedia | None ,
95+ int ,
9496]:
95- """Build a citation source, deduplicating by assigning numbers"""
96- if citation not in source_numbers :
97- source_numbers [citation ] = next_number
98- next_number += 1
99- number = source_numbers [citation ]
100-
101- source : UiPathConversationCitationSourceUrl | UiPathConversationCitationSourceMedia
97+ """Build a citation source, deduplicating by assigning numbers."""
10298 if citation .url is not None :
103- source = UiPathConversationCitationSourceUrl (
99+ if citation not in source_numbers :
100+ source_numbers [citation ] = next_number
101+ next_number += 1
102+ return UiPathConversationCitationSourceUrl (
104103 title = citation .title ,
105- number = number ,
104+ number = source_numbers [ citation ] ,
106105 url = citation .url ,
107- )
108- else :
109- source = UiPathConversationCitationSourceMedia (
106+ ), next_number
107+ elif citation .reference is not None and citation .page_number is not None :
108+ if citation not in source_numbers :
109+ source_numbers [citation ] = next_number
110+ next_number += 1
111+ return UiPathConversationCitationSourceMedia (
110112 title = citation .title ,
111- number = number ,
113+ number = source_numbers [ citation ] ,
112114 mime_type = None ,
113115 download_url = citation .reference ,
114116 page_number = citation .page_number ,
115- )
116- return source , next_number
117+ ), next_number
118+ else :
119+ return None , next_number
117120
118121
119122def _find_partial_tag_start (text : str ) -> int :
@@ -160,6 +163,9 @@ def _build_content_part_citation(
160163 citation , self ._source_numbers , self ._next_number
161164 )
162165
166+ if not source :
167+ return UiPathConversationContentPartChunkEvent (data = text )
168+
163169 return UiPathConversationContentPartChunkEvent (
164170 data = text ,
165171 citation = UiPathConversationCitationEvent (
@@ -236,6 +242,9 @@ def extract_citations_from_text(
236242
237243 if citation is not None :
238244 source , next_number = _make_source (citation , source_numbers , next_number )
245+ if not source :
246+ offset += length
247+ continue
239248 if length > 0 :
240249 citations .append (
241250 UiPathConversationCitationData (
0 commit comments