项目文件夹

文件
wehub-resource-sync 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
chore: import upstream snapshot with attribution
2026-07-13 13:02:24 +08:00

131 行
5.4 KiB
Python

"""Zep / Graphiti memory source.
Reads a JSON export of a Zep or Graphiti (OSS) knowledge graph and yields:
- episodes (verbatim ingested content) -> :class:`COGXEpisode`
- entity nodes -> :class:`COGXEntity`
- relation edges ("facts") -> :class:`COGXFact` carrying the
bi-temporal ``valid_at``/``invalid_at``/``expired_at`` fields
Expected shape (tolerant of key-name variants)::
{
"episodes": [{"uuid", "name", "content"|"episode_body", "created_at", ...}],
"entities"|"nodes": [{"uuid", "name", "labels"|"label", "summary", ...}],
"facts"|"edges": [{"uuid", "source_node_uuid", "target_node_uuid",
"name"|"relation", "fact", "valid_at", "invalid_at", ...}]
}
For OSS Graphiti the export JSON can be produced with a direct Cypher dump of
EntityNode/EpisodicNode/RELATES_TO records. Defaults to ``hybrid`` mode since
Graphiti keeps both verbatim episodes and a derived graph.
"""
import json
from pathlib import Path
from typing import Any, AsyncIterator, Dict, List, Union
from cognee.modules.migration.cogx import (
COGXEntity,
COGXEpisode,
COGXFact,
COGXRecord,
COGXScope,
COGXTurn,
parse_timestamp,
)
from cognee.modules.migration.sources.base import MemorySource
def _first_list(container: Dict[str, Any], *keys: str) -> List[Dict[str, Any]]:
for key in keys:
value = container.get(key)
if isinstance(value, list):
return [item for item in value if isinstance(item, dict)]
return []
class ZepSource(MemorySource):
source_system = "zep"
def __init__(self, data: Union[str, Path, Dict[str, Any]], mode: str = "hybrid"):
super().__init__(mode=mode)
self._data = data
def _load_raw(self) -> Dict[str, Any]:
data = self._data
if isinstance(data, (str, Path)):
data = json.loads(Path(data).read_text(encoding="utf-8"))
if not isinstance(data, dict):
raise ValueError("Unrecognized Zep/Graphiti export: expected a JSON object.")
return data
async def records(self) -> AsyncIterator[COGXRecord]:
data = self._load_raw()
for index, episode in enumerate(_first_list(data, "episodes", "episodic_nodes")):
content = episode.get("content") or episode.get("episode_body")
if not isinstance(content, str) or not content.strip():
continue
occurred_at = parse_timestamp(episode.get("valid_at") or episode.get("created_at"))
yield COGXEpisode(
external_system=self.source_system,
external_id=str(episode.get("uuid") or episode.get("id") or f"episode-{index}"),
title=episode.get("name"),
turns=[COGXTurn(role="episode", content=content, occurred_at=occurred_at)],
created_at=parse_timestamp(episode.get("created_at")),
scope=COGXScope(
user_id=episode.get("user_id"),
session_id=episode.get("group_id") or episode.get("session_id"),
),
metadata=(
{"source_description": episode.get("source_description")}
if episode.get("source_description")
else {}
),
)
for index, node in enumerate(_first_list(data, "entities", "nodes", "entity_nodes")):
name = node.get("name")
if not isinstance(name, str) or not name.strip():
continue
labels = node.get("labels") or node.get("label") or []
if isinstance(labels, str):
labels = [labels]
entity_type = next((label for label in labels if label != "Entity"), None)
yield COGXEntity(
external_system=self.source_system,
external_id=str(node.get("uuid") or node.get("id") or f"entity-{index}"),
name=name,
entity_type=entity_type,
description=node.get("summary") or node.get("description"),
attributes=node.get("attributes") or {},
created_at=parse_timestamp(node.get("created_at")),
scope=COGXScope(session_id=node.get("group_id")),
)
for index, edge in enumerate(_first_list(data, "facts", "edges", "entity_edges")):
subject_ref = edge.get("source_node_uuid") or edge.get("source")
object_ref = edge.get("target_node_uuid") or edge.get("target")
if not subject_ref or not object_ref:
continue
yield COGXFact(
external_system=self.source_system,
external_id=str(edge.get("uuid") or edge.get("id") or f"fact-{index}"),
subject_ref=str(subject_ref),
predicate=str(edge.get("name") or edge.get("relation") or "relates_to"),
object_ref=str(object_ref),
fact_text=edge.get("fact"),
valid_at=parse_timestamp(edge.get("valid_at")),
invalid_at=parse_timestamp(edge.get("invalid_at") or edge.get("expired_at")),
created_at=parse_timestamp(edge.get("created_at")),
provenance=[str(episode) for episode in edge.get("episodes") or []],
scope=COGXScope(session_id=edge.get("group_id")),
)
class GraphitiSource(ZepSource):
"""Alias for OSS Graphiti exports (same shape as Zep graph exports)."""
source_system = "graphiti"