2929from graphiti_core .llm_client .config import ModelSize
3030from graphiti_core .nodes import EntityNode , EpisodeType , EpisodicNode , create_entity_node_embeddings
3131from graphiti_core .prompts import prompt_library
32- from graphiti_core .prompts .dedupe_nodes import NodeDuplicate , NodeResolutions
32+ from graphiti_core .prompts .dedupe_nodes import NodeResolutions
3333from graphiti_core .prompts .extract_nodes import (
3434 ExtractedEntities ,
3535 ExtractedEntity ,
@@ -241,7 +241,25 @@ async def resolve_extracted_nodes(
241241 ]
242242 )
243243
244- existing_nodes_lists : list [list [EntityNode ]] = [result .nodes for result in search_results ]
244+ existing_nodes_dict : dict [str , EntityNode ] = {
245+ node .uuid : node for result in search_results for node in result .nodes
246+ }
247+
248+ existing_nodes : list [EntityNode ] = list (existing_nodes_dict .values ())
249+
250+ existing_nodes_context = (
251+ [
252+ {
253+ ** {
254+ 'idx' : i ,
255+ 'name' : candidate .name ,
256+ 'entity_types' : candidate .labels ,
257+ },
258+ ** candidate .attributes ,
259+ }
260+ for i , candidate in enumerate (existing_nodes )
261+ ],
262+ )
245263
246264 entity_types_dict : dict [str , BaseModel ] = entity_types if entity_types is not None else {}
247265
@@ -255,23 +273,13 @@ async def resolve_extracted_nodes(
255273 next ((item for item in node .labels if item != 'Entity' ), '' )
256274 ).__doc__
257275 or 'Default Entity Type' ,
258- 'duplication_candidates' : [
259- {
260- ** {
261- 'idx' : j ,
262- 'name' : candidate .name ,
263- 'entity_types' : candidate .labels ,
264- },
265- ** candidate .attributes ,
266- }
267- for j , candidate in enumerate (existing_nodes_lists [i ])
268- ],
269276 }
270277 for i , node in enumerate (extracted_nodes )
271278 ]
272279
273280 context = {
274281 'extracted_nodes' : extracted_nodes_context ,
282+ 'existing_nodes' : existing_nodes_context ,
275283 'episode_content' : episode .content if episode is not None else '' ,
276284 'previous_episodes' : [ep .content for ep in previous_episodes ]
277285 if previous_episodes is not None
@@ -294,8 +302,8 @@ async def resolve_extracted_nodes(
294302 extracted_node = extracted_nodes [resolution_id ]
295303
296304 resolved_node = (
297- existing_nodes_lists [ resolution_id ] [duplicate_idx ]
298- if 0 <= duplicate_idx < len (existing_nodes_lists [ resolution_id ] )
305+ existing_nodes [duplicate_idx ]
306+ if 0 <= duplicate_idx < len (existing_nodes )
299307 else extracted_node
300308 )
301309
@@ -309,70 +317,6 @@ async def resolve_extracted_nodes(
309317 return resolved_nodes , uuid_map
310318
311319
312- async def resolve_extracted_node (
313- llm_client : LLMClient ,
314- extracted_node : EntityNode ,
315- existing_nodes : list [EntityNode ],
316- episode : EpisodicNode | None = None ,
317- previous_episodes : list [EpisodicNode ] | None = None ,
318- entity_type : BaseModel | None = None ,
319- ) -> EntityNode :
320- start = time ()
321- if len (existing_nodes ) == 0 :
322- return extracted_node
323-
324- # Prepare context for LLM
325- existing_nodes_context = [
326- {
327- ** {
328- 'id' : i ,
329- 'name' : node .name ,
330- 'entity_types' : node .labels ,
331- },
332- ** node .attributes ,
333- }
334- for i , node in enumerate (existing_nodes )
335- ]
336-
337- extracted_node_context = {
338- 'name' : extracted_node .name ,
339- 'entity_type' : entity_type .__name__ if entity_type is not None else 'Entity' , # type: ignore
340- }
341-
342- context = {
343- 'existing_nodes' : existing_nodes_context ,
344- 'extracted_node' : extracted_node_context ,
345- 'entity_type_description' : entity_type .__doc__
346- if entity_type is not None
347- else 'Default Entity Type' ,
348- 'episode_content' : episode .content if episode is not None else '' ,
349- 'previous_episodes' : [ep .content for ep in previous_episodes ]
350- if previous_episodes is not None
351- else [],
352- }
353-
354- llm_response = await llm_client .generate_response (
355- prompt_library .dedupe_nodes .node (context ),
356- response_model = NodeDuplicate ,
357- model_size = ModelSize .small ,
358- )
359-
360- duplicate_id : int = llm_response .get ('duplicate_node_id' , - 1 )
361-
362- node = (
363- existing_nodes [duplicate_id ] if 0 <= duplicate_id < len (existing_nodes ) else extracted_node
364- )
365-
366- node .name = llm_response .get ('name' , '' )
367-
368- end = time ()
369- logger .debug (
370- f'Resolved node: { extracted_node .name } is { node .name } , in { (end - start ) * 1000 } ms'
371- )
372-
373- return node
374-
375-
376320async def extract_attributes_from_nodes (
377321 clients : GraphitiClients ,
378322 nodes : list [EntityNode ],
0 commit comments