pycontextdb 0.1.0__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (47) hide show
  1. contextdb/__init__.py +72 -0
  2. contextdb/agents/__init__.py +8 -0
  3. contextdb/agents/memory_bus.py +80 -0
  4. contextdb/agents/rl_manager.py +89 -0
  5. contextdb/cli.py +107 -0
  6. contextdb/client.py +516 -0
  7. contextdb/core/__init__.py +41 -0
  8. contextdb/core/config.py +89 -0
  9. contextdb/core/exceptions.py +29 -0
  10. contextdb/core/models.py +151 -0
  11. contextdb/dynamics/__init__.py +25 -0
  12. contextdb/dynamics/evolution.py +168 -0
  13. contextdb/dynamics/formation.py +193 -0
  14. contextdb/dynamics/retrieval.py +130 -0
  15. contextdb/graphs/__init__.py +17 -0
  16. contextdb/graphs/base.py +46 -0
  17. contextdb/graphs/causal.py +224 -0
  18. contextdb/graphs/entity.py +251 -0
  19. contextdb/graphs/semantic.py +156 -0
  20. contextdb/graphs/temporal.py +173 -0
  21. contextdb/integrations/__init__.py +10 -0
  22. contextdb/integrations/autogen.py +39 -0
  23. contextdb/integrations/crewai.py +41 -0
  24. contextdb/integrations/langchain.py +132 -0
  25. contextdb/integrations/openai_tools.py +124 -0
  26. contextdb/memory/__init__.py +9 -0
  27. contextdb/memory/experiential.py +102 -0
  28. contextdb/memory/factual.py +58 -0
  29. contextdb/memory/working.py +90 -0
  30. contextdb/privacy/__init__.py +9 -0
  31. contextdb/privacy/audit.py +199 -0
  32. contextdb/privacy/pii_detector.py +173 -0
  33. contextdb/privacy/retention.py +99 -0
  34. contextdb/py.typed +0 -0
  35. contextdb/store/__init__.py +15 -0
  36. contextdb/store/base.py +67 -0
  37. contextdb/store/sqlite_store.py +517 -0
  38. contextdb/store/vector_index.py +241 -0
  39. contextdb/utils/__init__.py +22 -0
  40. contextdb/utils/embeddings.py +159 -0
  41. contextdb/utils/llm.py +139 -0
  42. contextdb/utils/migrations.py +159 -0
  43. pycontextdb-0.1.0.dist-info/METADATA +589 -0
  44. pycontextdb-0.1.0.dist-info/RECORD +47 -0
  45. pycontextdb-0.1.0.dist-info/WHEEL +4 -0
  46. pycontextdb-0.1.0.dist-info/entry_points.txt +2 -0
  47. pycontextdb-0.1.0.dist-info/licenses/LICENSE +190 -0
@@ -0,0 +1,159 @@
1
+ """Migration tools — import from competitors, export to JSON.
2
+
3
+ Each importer accepts an iterable of dicts in the source system's shape and
4
+ translates them into :class:`~contextdb.core.models.MemoryItem` writes. We
5
+ keep the mapping forgiving: missing fields fall back to sensible defaults
6
+ so a partial dump still loads cleanly.
7
+ """
8
+
9
+ from __future__ import annotations
10
+
11
+ import json
12
+ from collections.abc import Iterable
13
+ from datetime import datetime
14
+ from pathlib import Path
15
+ from typing import TYPE_CHECKING, Any
16
+
17
+ from contextdb.core.models import MemoryItem, MemoryType
18
+
19
+ if TYPE_CHECKING:
20
+ from contextdb.client import ContextDB
21
+
22
+
23
+ def _parse_datetime(value: Any) -> datetime | None:
24
+ if value is None:
25
+ return None
26
+ if isinstance(value, datetime):
27
+ return value
28
+ try:
29
+ return datetime.fromisoformat(str(value))
30
+ except (TypeError, ValueError):
31
+ return None
32
+
33
+
34
+ class Mem0Importer:
35
+ """Import from a Mem0 JSON export.
36
+
37
+ Mem0 records typically carry ``memory`` (text), ``user_id``, ``metadata``,
38
+ and ISO ``created_at``. Anything beyond that lands in ``metadata``.
39
+ """
40
+
41
+ def __init__(self, client: ContextDB) -> None:
42
+ self.client = client
43
+
44
+ async def import_records(self, records: Iterable[dict[str, Any]]) -> int:
45
+ count = 0
46
+ for record in records:
47
+ content = record.get("memory") or record.get("content") or ""
48
+ if not content:
49
+ continue
50
+ await self.client.add(
51
+ content=str(content),
52
+ metadata=dict(record.get("metadata", {})),
53
+ event_time=_parse_datetime(record.get("created_at")),
54
+ )
55
+ count += 1
56
+ return count
57
+
58
+
59
+ class ZepImporter:
60
+ """Import from a Zep session dump."""
61
+
62
+ def __init__(self, client: ContextDB) -> None:
63
+ self.client = client
64
+
65
+ async def import_records(self, records: Iterable[dict[str, Any]]) -> int:
66
+ count = 0
67
+ for record in records:
68
+ content = record.get("content") or record.get("message") or ""
69
+ if not content:
70
+ continue
71
+ meta = dict(record.get("metadata", {}))
72
+ if "role" in record:
73
+ meta.setdefault("role", record["role"])
74
+ await self.client.add(
75
+ content=str(content),
76
+ metadata=meta,
77
+ event_time=_parse_datetime(record.get("created_at")),
78
+ )
79
+ count += 1
80
+ return count
81
+
82
+
83
+ class LangChainImporter:
84
+ """Import from LangChain ``ChatMessageHistory`` dumps."""
85
+
86
+ def __init__(self, client: ContextDB) -> None:
87
+ self.client = client
88
+
89
+ async def import_records(self, messages: Iterable[dict[str, Any]]) -> int:
90
+ count = 0
91
+ for message in messages:
92
+ text = message.get("content") or message.get("text") or ""
93
+ if not text:
94
+ continue
95
+ role = message.get("type") or message.get("role") or "human"
96
+ await self.client.add(
97
+ content=f"{role}: {text}",
98
+ metadata={"role": role},
99
+ )
100
+ count += 1
101
+ return count
102
+
103
+
104
+ class JSONExporter:
105
+ """Dump the entire store as a JSON array of memory records."""
106
+
107
+ def __init__(self, client: ContextDB) -> None:
108
+ self.client = client
109
+
110
+ async def export(self, path: str | Path) -> int:
111
+ await self.client._ensure_init()
112
+ store = self.client._require_store()
113
+ memories = await store.list_memories(limit=100000)
114
+ records = [self._to_record(m) for m in memories]
115
+ Path(path).write_text(json.dumps(records, indent=2, default=str))
116
+ return len(records)
117
+
118
+ @staticmethod
119
+ def _to_record(item: MemoryItem) -> dict[str, Any]:
120
+ return {
121
+ "id": item.id,
122
+ "content": item.content,
123
+ "memory_type": item.memory_type.value,
124
+ "source": item.source,
125
+ "metadata": item.metadata,
126
+ "event_time": item.event_time.isoformat() if item.event_time else None,
127
+ "created_at": item.created_at.isoformat(),
128
+ "updated_at": item.updated_at.isoformat(),
129
+ "entity_mentions": item.entity_mentions,
130
+ "tags": item.tags,
131
+ "confidence": item.confidence,
132
+ "status": item.status.value,
133
+ }
134
+
135
+
136
+ class JSONImporter:
137
+ """Re-import a :class:`JSONExporter` dump."""
138
+
139
+ def __init__(self, client: ContextDB) -> None:
140
+ self.client = client
141
+
142
+ async def import_path(self, path: str | Path) -> int:
143
+ records = json.loads(Path(path).read_text())
144
+ assert isinstance(records, list)
145
+ count = 0
146
+ for record in records:
147
+ content = record.get("content")
148
+ if not content:
149
+ continue
150
+ mt = MemoryType(record.get("memory_type", "FACTUAL"))
151
+ await self.client.add(
152
+ content=content,
153
+ memory_type=mt,
154
+ metadata=dict(record.get("metadata", {})),
155
+ event_time=_parse_datetime(record.get("event_time")),
156
+ entity_mentions=list(record.get("entity_mentions", [])),
157
+ )
158
+ count += 1
159
+ return count