c889a57b6b
Test Suites / Build CI Environment (push) Has been cancelled
Test Suites / Basic Tests (push) Has been cancelled
Test Suites / End-to-End Tests (push) Has been cancelled
Test Suites / CLI Tests (push) Has been cancelled
Test Suites / Slow End-to-End Tests (push) Has been cancelled
Test Suites / Graph Database Tests (push) Has been cancelled
Test Suites / Vector DB Tests (push) Has been cancelled
Test Suites / Temporal Graph Test (push) Has been cancelled
Test Suites / Search Test on Different DBs (push) Has been cancelled
Test Suites / Example Tests (push) Has been cancelled
Test Suites / Notebook Tests (push) Has been cancelled
Test Suites / OS and Python Tests Ubuntu (push) Has been cancelled
Test Suites / OS and Python Tests Extended (push) Has been cancelled
Test Suites / LLM Test Suite (push) Has been cancelled
Test Suites / S3 File Storage Test (push) Has been cancelled
Test Suites / Run Integration Tests (push) Has been cancelled
Test Suites / MCP Tests (push) Has been cancelled
Test Suites / Docker Compose Test (push) Has been cancelled
Test Suites / Docker CI test (push) Has been cancelled
Test Suites / Relational DB Migration Tests (push) Has been cancelled
Test Suites / Distributed Cognee Test (push) Has been cancelled
Test Suites / DB Examples Tests (push) Has been cancelled
Test Suites / Test Completion Status (push) Has been cancelled
Test Suites / Claude Code Review (push) Has been cancelled
Test Suites / basic checks (push) Has been cancelled
build | Build and Push Cognee MCP Docker Image to dockerhub / docker-build-and-push (push) Has been cancelled
Scorecard supply-chain security / Scorecard analysis (push) Has been cancelled
build | Build and Push Docker Image to dockerhub / docker-build-and-push (push) Has been cancelled
Weighted Edges Tests / Test Weighted Edges Core Functionality (3.11) (push) Has been cancelled
Weighted Edges Tests / Test Weighted Edges Core Functionality (3.12) (push) Has been cancelled
Weighted Edges Tests / Test Weighted Edges with Different Graph Databases (kuzu, kuzu) (push) Has been cancelled
Weighted Edges Tests / Test Weighted Edges with Different Graph Databases (neo4j, neo4j) (push) Has been cancelled
Weighted Edges Tests / Test Weighted Edges Examples (push) Has been cancelled
Weighted Edges Tests / Code Quality for Weighted Edges (push) Has been cancelled
108 lines
3.3 KiB
Python
108 lines
3.3 KiB
Python
import string
|
|
from typing import List
|
|
from collections import Counter
|
|
|
|
from cognee.modules.graph.cognee_graph.CogneeGraphElements import Edge
|
|
from cognee.modules.retrieval.utils.stop_words import DEFAULT_STOP_WORDS
|
|
from cognee.shared.logging_utils import get_logger
|
|
|
|
logger = get_logger()
|
|
|
|
|
|
def _get_top_n_frequent_words(
|
|
text: str, stop_words: set = None, top_n: int = 3, separator: str = ", "
|
|
) -> str:
|
|
"""Concatenates the top N frequent words in text."""
|
|
if stop_words is None:
|
|
stop_words = DEFAULT_STOP_WORDS
|
|
|
|
words = [word.lower().strip(string.punctuation) for word in text.split()]
|
|
words = [word for word in words if word and word not in stop_words]
|
|
|
|
top_words = [word for word, freq in Counter(words).most_common(top_n)]
|
|
return separator.join(top_words)
|
|
|
|
|
|
def _create_title_from_text(text: str, first_n_words: int = 7, top_n_words: int = 3) -> str:
|
|
"""Creates a title by combining first words with most frequent words from the text."""
|
|
first_words = text.split()[:first_n_words]
|
|
top_words = _get_top_n_frequent_words(text, top_n=top_n_words)
|
|
return f"{' '.join(first_words)}... [{top_words}]"
|
|
|
|
|
|
def _extract_nodes_from_edges(retrieved_edges: List[Edge]) -> dict:
|
|
"""Creates a dictionary of nodes with their names and content."""
|
|
|
|
logger.debug(
|
|
"Extracting nodes from retrieved edges",
|
|
extra={"edge_count": len(retrieved_edges)},
|
|
)
|
|
|
|
nodes = {}
|
|
|
|
for edge in retrieved_edges:
|
|
for node in (edge.node1, edge.node2):
|
|
if node.id in nodes:
|
|
continue
|
|
|
|
text = node.attributes.get("text")
|
|
if text:
|
|
name = _create_title_from_text(text)
|
|
content = text
|
|
else:
|
|
name = node.attributes.get("name", "Unnamed Node")
|
|
content = node.attributes.get("description", name)
|
|
|
|
nodes[node.id] = {"node": node, "name": name, "content": content}
|
|
|
|
return nodes
|
|
|
|
|
|
async def resolve_edges_to_text(retrieved_edges: List[Edge]) -> str:
|
|
"""Converts retrieved graph edges into a human-readable string format."""
|
|
if not retrieved_edges:
|
|
return ""
|
|
|
|
nodes = _extract_nodes_from_edges(retrieved_edges)
|
|
|
|
node_section = "\n".join(
|
|
f"Node: {info['name']}\n__node_content_start__\n{info['content']}\n__node_content_end__\n"
|
|
for info in nodes.values()
|
|
)
|
|
|
|
connections = []
|
|
|
|
logger.debug(
|
|
"Resolving edges to text",
|
|
extra={"edge_count": len(retrieved_edges)},
|
|
)
|
|
|
|
for edge in retrieved_edges:
|
|
source_name = nodes[edge.node1.id]["name"]
|
|
target_name = nodes[edge.node2.id]["name"]
|
|
edge_label = (
|
|
edge.attributes.get("relationship_type")
|
|
or edge.attributes.get("relationship_name")
|
|
or edge.attributes.get("edge_text")
|
|
)
|
|
|
|
line = f"{source_name} --[{edge_label}]--> {target_name}"
|
|
|
|
description = edge.attributes.get("edge_text")
|
|
if description and description != edge_label:
|
|
line += f" ({description})"
|
|
|
|
connections.append(line)
|
|
|
|
connection_section = "\n".join(connections)
|
|
|
|
logger.info(
|
|
"Completed resolving edges to text",
|
|
extra={
|
|
"node_count": len(nodes),
|
|
"connection_count": len(connections),
|
|
},
|
|
)
|
|
|
|
return f"Nodes:\n{node_section}\n\nConnections:\n{connection_section}"
|