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"