77from langchain_core .messages import (
88 AIMessageChunk ,
99 BaseMessage ,
10+ Citation ,
1011 HumanMessage ,
1112 TextContentBlock ,
1213 ToolCallChunk ,
1314 ToolMessage ,
1415)
1516from uipath .core .chat import (
17+ UiPathConversationCitationEndEvent ,
18+ UiPathConversationCitationEvent ,
19+ UiPathConversationCitationSource ,
20+ UiPathConversationCitationStartEvent ,
1621 UiPathConversationContentPartChunkEvent ,
1722 UiPathConversationContentPartEndEvent ,
1823 UiPathConversationContentPartEvent ,
@@ -184,13 +189,50 @@ def map_event(
184189 text_block = cast (TextContentBlock , block )
185190 text = text_block ["text" ]
186191
187- msg_event .content_part = UiPathConversationContentPartEvent (
188- content_part_id = f"chunk-{ message .id } -0" ,
189- chunk = UiPathConversationContentPartChunkEvent (
190- data = text ,
191- content_part_sequence = 0 ,
192- ),
193- )
192+ # Map citations if present
193+ annotations = text_block .get ("annotations" , [])
194+ citation_annotations = [
195+ cast (Citation , annotation )
196+ for annotation in annotations
197+ if annotation .get ("type" ) == "citation"
198+ ]
199+
200+ if citation_annotations :
201+ for citation_annotation in citation_annotations :
202+ # Build citation source, only include url if present
203+ block_index = text_block .get ("index" , 0 )
204+ block_index = block_index // 2 + 1
205+ source_args = {
206+ "title" : citation_annotation .get ("title" ),
207+ "number" : block_index ,
208+ }
209+ if citation_annotation .get ("url" ) is not None :
210+ source_args ["url" ] = citation_annotation .get ("url" )
211+
212+ citation_source = UiPathConversationCitationSource (
213+ ** source_args
214+ )
215+
216+ msg_event .content_part = UiPathConversationContentPartEvent (
217+ content_part_id = f"chunk-{ message .id } -0" ,
218+ chunk = UiPathConversationContentPartChunkEvent (
219+ data = citation_annotation ["cited_text" ],
220+ citation = UiPathConversationCitationEvent (
221+ citation_id = str (uuid4 ()),
222+ start = UiPathConversationCitationStartEvent (),
223+ end = UiPathConversationCitationEndEvent (
224+ sources = [citation_source ]
225+ ),
226+ ),
227+ ),
228+ )
229+ else :
230+ msg_event .content_part = UiPathConversationContentPartEvent (
231+ content_part_id = f"chunk-{ message .id } -0" ,
232+ chunk = UiPathConversationContentPartChunkEvent (
233+ data = text
234+ ),
235+ )
194236
195237 elif block_type == "tool_call_chunk" :
196238 tool_chunk_block = cast (ToolCallChunk , block )
@@ -204,10 +246,7 @@ def map_event(
204246
205247 msg_event .content_part = UiPathConversationContentPartEvent (
206248 content_part_id = f"chunk-{ message .id } -0" ,
207- chunk = UiPathConversationContentPartChunkEvent (
208- data = args ,
209- content_part_sequence = 0 ,
210- ),
249+ chunk = UiPathConversationContentPartChunkEvent (data = args ),
211250 )
212251 # Continue so that multiple tool_call_chunks in the same block list
213252 # are handled correctly
@@ -217,10 +256,7 @@ def map_event(
217256 elif isinstance (message .content , str ) and message .content :
218257 msg_event .content_part = UiPathConversationContentPartEvent (
219258 content_part_id = f"content-{ message .id } " ,
220- chunk = UiPathConversationContentPartChunkEvent (
221- data = message .content ,
222- content_part_sequence = 0 ,
223- ),
259+ chunk = UiPathConversationContentPartChunkEvent (data = message .content ),
224260 )
225261
226262 if (
@@ -269,12 +305,12 @@ def map_event(
269305 tool_call_id = message .tool_call_id ,
270306 start = UiPathConversationToolCallStartEvent (
271307 tool_name = message .name ,
272- arguments = None ,
308+ input = None ,
273309 timestamp = timestamp ,
274310 ),
275311 end = UiPathConversationToolCallEndEvent (
276312 timestamp = timestamp ,
277- result = UiPathInlineValue (inline = content_value ),
313+ output = UiPathInlineValue (inline = content_value ),
278314 ),
279315 ),
280316 )
0 commit comments