generated from coulomb/repo-seed
55 lines
1.6 KiB
Python
55 lines
1.6 KiB
Python
from __future__ import annotations
|
|
|
|
from dataclasses import dataclass, field
|
|
|
|
from .models import KnowledgeArtifact
|
|
|
|
|
|
@dataclass(frozen=True)
|
|
class RelationshipEdge:
|
|
source: str
|
|
target: str
|
|
type: str
|
|
|
|
|
|
@dataclass(frozen=True)
|
|
class RelationshipSummary:
|
|
nodes: list[str]
|
|
edges: list[RelationshipEdge]
|
|
relationship_types: dict[str, int] = field(default_factory=dict)
|
|
|
|
@property
|
|
def node_count(self) -> int:
|
|
return len(self.nodes)
|
|
|
|
@property
|
|
def edge_count(self) -> int:
|
|
return len(self.edges)
|
|
|
|
|
|
def relationship_summary(artifacts: list[KnowledgeArtifact]) -> RelationshipSummary:
|
|
ids = {artifact.id for artifact in artifacts}
|
|
edges: list[RelationshipEdge] = []
|
|
type_counts: dict[str, int] = {}
|
|
for artifact in artifacts:
|
|
for relationship in artifact.relationships:
|
|
target = relationship.get("target")
|
|
relation_type = str(relationship.get("type") or "related")
|
|
if isinstance(target, str) and target in ids:
|
|
edges.append(RelationshipEdge(artifact.id, target, relation_type))
|
|
type_counts[relation_type] = type_counts.get(relation_type, 0) + 1
|
|
return RelationshipSummary(
|
|
nodes=sorted(ids),
|
|
edges=edges,
|
|
relationship_types=dict(sorted(type_counts.items())),
|
|
)
|
|
|
|
|
|
def export_mermaid(summary: RelationshipSummary) -> str:
|
|
lines = ["graph TD"]
|
|
for node in summary.nodes:
|
|
lines.append(f" {node}")
|
|
for edge in summary.edges:
|
|
lines.append(f" {edge.source} -->|{edge.type}| {edge.target}")
|
|
return "\n".join(lines) + "\n"
|