cortexdbai 0.4.1__tar.gz → 0.4.2__tar.gz
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.
- {cortexdbai-0.4.1 → cortexdbai-0.4.2}/PKG-INFO +8 -1
- {cortexdbai-0.4.1 → cortexdbai-0.4.2}/README.md +140 -140
- {cortexdbai-0.4.1 → cortexdbai-0.4.2}/cortexdb/__init__.py +71 -71
- cortexdbai-0.4.2/cortexdb/integrations/ag2/__init__.py +21 -0
- cortexdbai-0.4.2/cortexdb/integrations/ag2/agent.py +183 -0
- cortexdbai-0.4.2/cortexdb/integrations/ag2/tools.py +165 -0
- cortexdbai-0.4.2/cortexdb/integrations/agno/__init__.py +13 -0
- cortexdbai-0.4.2/cortexdb/integrations/agno/memory.py +113 -0
- cortexdbai-0.4.2/cortexdb/integrations/agno/tools.py +97 -0
- cortexdbai-0.4.2/cortexdb/integrations/langchain/__init__.py +29 -0
- cortexdbai-0.4.2/cortexdb/integrations/langchain/memory.py +141 -0
- cortexdbai-0.4.2/cortexdb/integrations/langchain/retriever.py +74 -0
- cortexdbai-0.4.2/cortexdb/integrations/langchain/tools.py +121 -0
- {cortexdbai-0.4.1 → cortexdbai-0.4.2}/pyproject.toml +12 -1
- {cortexdbai-0.4.1 → cortexdbai-0.4.2}/.gitignore +0 -0
- {cortexdbai-0.4.1 → cortexdbai-0.4.2}/cortexdb/integrations/__init__.py +0 -0
- {cortexdbai-0.4.1 → cortexdbai-0.4.2}/cortexdb/integrations/autogen/__init__.py +0 -0
- {cortexdbai-0.4.1 → cortexdbai-0.4.2}/cortexdb/integrations/autogen/agent.py +0 -0
- {cortexdbai-0.4.1 → cortexdbai-0.4.2}/cortexdb/integrations/autogen/tools.py +0 -0
- {cortexdbai-0.4.1 → cortexdbai-0.4.2}/cortexdb/integrations/beeai/__init__.py +0 -0
- {cortexdbai-0.4.1 → cortexdbai-0.4.2}/cortexdb/integrations/beeai/memory.py +0 -0
- {cortexdbai-0.4.1 → cortexdbai-0.4.2}/cortexdb/integrations/beeai/tools.py +0 -0
- {cortexdbai-0.4.1 → cortexdbai-0.4.2}/cortexdb/integrations/camel/__init__.py +0 -0
- {cortexdbai-0.4.1 → cortexdbai-0.4.2}/cortexdb/integrations/camel/memory.py +0 -0
- {cortexdbai-0.4.1 → cortexdbai-0.4.2}/cortexdb/integrations/camel/tools.py +0 -0
- {cortexdbai-0.4.1 → cortexdbai-0.4.2}/cortexdb/integrations/controlflow/__init__.py +0 -0
- {cortexdbai-0.4.1 → cortexdbai-0.4.2}/cortexdb/integrations/controlflow/memory.py +0 -0
- {cortexdbai-0.4.1 → cortexdbai-0.4.2}/cortexdb/integrations/crewai/__init__.py +0 -0
- {cortexdbai-0.4.1 → cortexdbai-0.4.2}/cortexdb/integrations/crewai/memory.py +0 -0
- {cortexdbai-0.4.1 → cortexdbai-0.4.2}/cortexdb/integrations/crewai/tools.py +0 -0
- {cortexdbai-0.4.1 → cortexdbai-0.4.2}/cortexdb/integrations/deepinfra/__init__.py +0 -0
- {cortexdbai-0.4.1 → cortexdbai-0.4.2}/cortexdb/integrations/deepinfra/config.py +0 -0
- {cortexdbai-0.4.1 → cortexdbai-0.4.2}/cortexdb/integrations/deepinfra/embeddings.py +0 -0
- {cortexdbai-0.4.1 → cortexdbai-0.4.2}/cortexdb/integrations/deepinfra/openai_compat.py +0 -0
- {cortexdbai-0.4.1 → cortexdbai-0.4.2}/cortexdb/integrations/dify/__init__.py +0 -0
- {cortexdbai-0.4.1 → cortexdbai-0.4.2}/cortexdb/integrations/dify/manifest.yaml +0 -0
- {cortexdbai-0.4.1 → cortexdbai-0.4.2}/cortexdb/integrations/dify/tool.py +0 -0
- {cortexdbai-0.4.1 → cortexdbai-0.4.2}/cortexdb/integrations/dspy/__init__.py +0 -0
- {cortexdbai-0.4.1 → cortexdbai-0.4.2}/cortexdb/integrations/dspy/memory.py +0 -0
- {cortexdbai-0.4.1 → cortexdbai-0.4.2}/cortexdb/integrations/dspy/retriever.py +0 -0
- {cortexdbai-0.4.1 → cortexdbai-0.4.2}/cortexdb/integrations/fireworks/__init__.py +0 -0
- {cortexdbai-0.4.1 → cortexdbai-0.4.2}/cortexdb/integrations/fireworks/config.py +0 -0
- {cortexdbai-0.4.1 → cortexdbai-0.4.2}/cortexdb/integrations/fireworks/embeddings.py +0 -0
- {cortexdbai-0.4.1 → cortexdbai-0.4.2}/cortexdb/integrations/fireworks/openai_compat.py +0 -0
- {cortexdbai-0.4.1 → cortexdbai-0.4.2}/cortexdb/integrations/flowise/__init__.py +0 -0
- {cortexdbai-0.4.1 → cortexdbai-0.4.2}/cortexdb/integrations/flowise/node.py +0 -0
- {cortexdbai-0.4.1 → cortexdbai-0.4.2}/cortexdb/integrations/google_adk/__init__.py +0 -0
- {cortexdbai-0.4.1 → cortexdbai-0.4.2}/cortexdb/integrations/google_adk/tools.py +0 -0
- {cortexdbai-0.4.1 → cortexdbai-0.4.2}/cortexdb/integrations/groq/__init__.py +0 -0
- {cortexdbai-0.4.1 → cortexdbai-0.4.2}/cortexdb/integrations/groq/config.py +0 -0
- {cortexdbai-0.4.1 → cortexdbai-0.4.2}/cortexdb/integrations/groq/embeddings.py +0 -0
- {cortexdbai-0.4.1 → cortexdbai-0.4.2}/cortexdb/integrations/groq/openai_compat.py +0 -0
- {cortexdbai-0.4.1 → cortexdbai-0.4.2}/cortexdb/integrations/hermes/__init__.py +0 -0
- {cortexdbai-0.4.1 → cortexdbai-0.4.2}/cortexdb/integrations/hermes/provider.py +0 -0
- {cortexdbai-0.4.1 → cortexdbai-0.4.2}/cortexdb/integrations/instructor/__init__.py +0 -0
- {cortexdbai-0.4.1 → cortexdbai-0.4.2}/cortexdb/integrations/instructor/memory.py +0 -0
- {cortexdbai-0.4.1 → cortexdbai-0.4.2}/cortexdb/integrations/langgraph/__init__.py +0 -0
- {cortexdbai-0.4.1 → cortexdbai-0.4.2}/cortexdb/integrations/langgraph/memory.py +0 -0
- {cortexdbai-0.4.1 → cortexdbai-0.4.2}/cortexdb/integrations/letta/__init__.py +0 -0
- {cortexdbai-0.4.1 → cortexdbai-0.4.2}/cortexdb/integrations/letta/storage.py +0 -0
- {cortexdbai-0.4.1 → cortexdbai-0.4.2}/cortexdb/integrations/llamaindex/__init__.py +0 -0
- {cortexdbai-0.4.1 → cortexdbai-0.4.2}/cortexdb/integrations/llamaindex/memory.py +0 -0
- {cortexdbai-0.4.1 → cortexdbai-0.4.2}/cortexdb/integrations/nemo_guardrails/__init__.py +0 -0
- {cortexdbai-0.4.1 → cortexdbai-0.4.2}/cortexdb/integrations/nemo_guardrails/actions.py +0 -0
- {cortexdbai-0.4.1 → cortexdbai-0.4.2}/cortexdb/integrations/nemo_guardrails/knowledge_base.py +0 -0
- {cortexdbai-0.4.1 → cortexdbai-0.4.2}/cortexdb/integrations/ollama/__init__.py +0 -0
- {cortexdbai-0.4.1 → cortexdbai-0.4.2}/cortexdb/integrations/ollama/config.py +0 -0
- {cortexdbai-0.4.1 → cortexdbai-0.4.2}/cortexdb/integrations/ollama/embeddings.py +0 -0
- {cortexdbai-0.4.1 → cortexdbai-0.4.2}/cortexdb/integrations/openai_agents/__init__.py +0 -0
- {cortexdbai-0.4.1 → cortexdbai-0.4.2}/cortexdb/integrations/openai_agents/tools.py +0 -0
- {cortexdbai-0.4.1 → cortexdbai-0.4.2}/cortexdb/integrations/prefect/__init__.py +0 -0
- {cortexdbai-0.4.1 → cortexdbai-0.4.2}/cortexdb/integrations/prefect/blocks.py +0 -0
- {cortexdbai-0.4.1 → cortexdbai-0.4.2}/cortexdb/integrations/prefect/tasks.py +0 -0
- {cortexdbai-0.4.1 → cortexdbai-0.4.2}/cortexdb/integrations/pydanticai/__init__.py +0 -0
- {cortexdbai-0.4.1 → cortexdbai-0.4.2}/cortexdb/integrations/pydanticai/dependencies.py +0 -0
- {cortexdbai-0.4.1 → cortexdbai-0.4.2}/cortexdb/integrations/pydanticai/tools.py +0 -0
- {cortexdbai-0.4.1 → cortexdbai-0.4.2}/cortexdb/integrations/smolagents/__init__.py +0 -0
- {cortexdbai-0.4.1 → cortexdbai-0.4.2}/cortexdb/integrations/smolagents/tools.py +0 -0
- {cortexdbai-0.4.1 → cortexdbai-0.4.2}/cortexdb/integrations/temporal/__init__.py +0 -0
- {cortexdbai-0.4.1 → cortexdbai-0.4.2}/cortexdb/integrations/temporal/activities.py +0 -0
- {cortexdbai-0.4.1 → cortexdbai-0.4.2}/cortexdb/integrations/temporal/interceptor.py +0 -0
- {cortexdbai-0.4.1 → cortexdbai-0.4.2}/cortexdb/integrations/together/__init__.py +0 -0
- {cortexdbai-0.4.1 → cortexdbai-0.4.2}/cortexdb/integrations/together/config.py +0 -0
- {cortexdbai-0.4.1 → cortexdbai-0.4.2}/cortexdb/integrations/together/embeddings.py +0 -0
- {cortexdbai-0.4.1 → cortexdbai-0.4.2}/cortexdb/integrations/together/openai_compat.py +0 -0
- {cortexdbai-0.4.1 → cortexdbai-0.4.2}/cortexdb/integrations/vllm/__init__.py +0 -0
- {cortexdbai-0.4.1 → cortexdbai-0.4.2}/cortexdb/integrations/vllm/config.py +0 -0
- {cortexdbai-0.4.1 → cortexdbai-0.4.2}/cortexdb/integrations/vllm/embeddings.py +0 -0
- {cortexdbai-0.4.1 → cortexdbai-0.4.2}/cortexdb/integrations/vllm/openai_compat.py +0 -0
- {cortexdbai-0.4.1 → cortexdbai-0.4.2}/cortexdb/py.typed +0 -0
- {cortexdbai-0.4.1 → cortexdbai-0.4.2}/cortexdb/v1/__init__.py +0 -0
- {cortexdbai-0.4.1 → cortexdbai-0.4.2}/cortexdb/v1/client.py +0 -0
- {cortexdbai-0.4.1 → cortexdbai-0.4.2}/cortexdb/v1/exceptions.py +0 -0
- {cortexdbai-0.4.1 → cortexdbai-0.4.2}/tests/__init__.py +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: cortexdbai
|
|
3
|
-
Version: 0.4.
|
|
3
|
+
Version: 0.4.2
|
|
4
4
|
Summary: The Long-Term Memory Layer for AI Systems
|
|
5
5
|
Project-URL: Homepage, https://cortexdb.ai
|
|
6
6
|
Project-URL: Documentation, https://docs.cortexdb.ai
|
|
@@ -25,8 +25,13 @@ Requires-Dist: httpx>=0.24
|
|
|
25
25
|
Requires-Dist: pydantic>=2.0
|
|
26
26
|
Requires-Dist: requests>=2.31
|
|
27
27
|
Requires-Dist: tenacity>=8.0
|
|
28
|
+
Provides-Extra: ag2
|
|
29
|
+
Requires-Dist: ag2>=0.4; extra == 'ag2'
|
|
30
|
+
Provides-Extra: agno
|
|
31
|
+
Requires-Dist: agno>=1.0; extra == 'agno'
|
|
28
32
|
Provides-Extra: all-integrations
|
|
29
33
|
Requires-Dist: ag2>=0.4; extra == 'all-integrations'
|
|
34
|
+
Requires-Dist: agno>=1.0; extra == 'all-integrations'
|
|
30
35
|
Requires-Dist: beeai-framework>=0.1; extra == 'all-integrations'
|
|
31
36
|
Requires-Dist: camel-ai>=0.2; extra == 'all-integrations'
|
|
32
37
|
Requires-Dist: controlflow>=0.11; extra == 'all-integrations'
|
|
@@ -77,6 +82,8 @@ Provides-Extra: hermes
|
|
|
77
82
|
Provides-Extra: instructor
|
|
78
83
|
Requires-Dist: instructor>=1.0; extra == 'instructor'
|
|
79
84
|
Requires-Dist: pydantic>=2.0; extra == 'instructor'
|
|
85
|
+
Provides-Extra: langchain
|
|
86
|
+
Requires-Dist: langchain-core>=0.3; extra == 'langchain'
|
|
80
87
|
Provides-Extra: langgraph
|
|
81
88
|
Requires-Dist: langchain-core>=0.3; extra == 'langgraph'
|
|
82
89
|
Requires-Dist: langgraph-checkpoint>=2.0; extra == 'langgraph'
|
|
@@ -1,140 +1,140 @@
|
|
|
1
|
-
# CortexDB Python SDK
|
|
2
|
-
|
|
3
|
-
**The Long-Term Memory Layer for AI Systems.**
|
|
4
|
-
|
|
5
|
-
CortexDB gives your AI agents persistent, structured memory. Capture experiences, then recall a stratified pack (events, facts, beliefs, episodes, concepts) or get a grounded answer — all scoped to a hierarchical `scope` path.
|
|
6
|
-
|
|
7
|
-
[](https://pypi.org/project/cortexdbai/)
|
|
8
|
-
[](https://pypi.org/project/cortexdbai/)
|
|
9
|
-
[](https://github.com/cortexdb/cortexdb/blob/main/LICENSE)
|
|
10
|
-
|
|
11
|
-
This SDK targets the **v1 API** (`/v1/experience`, `/v1/recall`, `/v1/answer`, …), PASETO auth, and hierarchical scopes. The pre-0.3 `remember()`/`tenant_id` client was retired — `Cortex` is now an alias of `V1Client`.
|
|
12
|
-
|
|
13
|
-
## Installation
|
|
14
|
-
|
|
15
|
-
```bash
|
|
16
|
-
pip install cortexdbai
|
|
17
|
-
```
|
|
18
|
-
|
|
19
|
-
## Quick start
|
|
20
|
-
|
|
21
|
-
```python
|
|
22
|
-
from cortexdb import Cortex
|
|
23
|
-
|
|
24
|
-
# Local `docker run` with auth disabled (CORTEX_API_KEY unset on the server):
|
|
25
|
-
with Cortex("http://localhost:3141") as c:
|
|
26
|
-
c.experience("ws:demo", text="Priya at Acme signed for 200 seats. Q3 close.")
|
|
27
|
-
pack = c.recall("ws:demo", query="How many seats did Acme sign for?")
|
|
28
|
-
print(pack["context_block"])
|
|
29
|
-
```
|
|
30
|
-
|
|
31
|
-
### Hosted / multi-tenant (PASETO bearer + actor)
|
|
32
|
-
|
|
33
|
-
```python
|
|
34
|
-
with Cortex(
|
|
35
|
-
"https://api-v1.cortexdb.ai",
|
|
36
|
-
actor="user:alice",
|
|
37
|
-
bearer="v4.public…", # PASETO v4 public or JWT (RS256/ES256)
|
|
38
|
-
) as c:
|
|
39
|
-
out = c.answer(
|
|
40
|
-
"org:initech/user:alice",
|
|
41
|
-
"What did Alice say about coffee?",
|
|
42
|
-
)
|
|
43
|
-
print(out["answer"])
|
|
44
|
-
```
|
|
45
|
-
|
|
46
|
-
### One-call signup (no prior credentials)
|
|
47
|
-
|
|
48
|
-
```python
|
|
49
|
-
from cortexdb import Cortex
|
|
50
|
-
|
|
51
|
-
c = Cortex.signup() # POST /v1/auth/signup → free-tier PASETO
|
|
52
|
-
c.experience(c.actor, text="hello, memory!")
|
|
53
|
-
print(c.recall(c.actor, query="what did I say?")["context_block"])
|
|
54
|
-
```
|
|
55
|
-
|
|
56
|
-
## Core operations
|
|
57
|
-
|
|
58
|
-
```python
|
|
59
|
-
# Write — async by default (202); pass wait= for synchronous indexing.
|
|
60
|
-
c.experience("ws:demo", text="Deployed payments-service v3.1 to prod.")
|
|
61
|
-
c.experience("ws:demo", text="Rolled back auth-gateway.", wait="indexed")
|
|
62
|
-
|
|
63
|
-
# Recall — returns a StratifiedPack { context_block, layers, provenance }.
|
|
64
|
-
pack = c.recall("ws:demo", query="recent deploys", view="holistic")
|
|
65
|
-
|
|
66
|
-
# Answer — recall + LLM render with citations.
|
|
67
|
-
ans = c.answer("ws:demo", "What changed in payments recently?")
|
|
68
|
-
|
|
69
|
-
# Forget — GDPR erasure. confirm_all wipes the whole scope.
|
|
70
|
-
c.forget("ws:demo", confirm_all=True, cascade="redact_events",
|
|
71
|
-
audit_note="GDPR Article 17 request")
|
|
72
|
-
|
|
73
|
-
# Layer reads (paginated { items, has_more }).
|
|
74
|
-
c.events("ws:demo")
|
|
75
|
-
c.facts("ws:demo")
|
|
76
|
-
c.beliefs("ws:demo")
|
|
77
|
-
c.episodes("ws:demo")
|
|
78
|
-
c.understanding("ws:demo")
|
|
79
|
-
```
|
|
80
|
-
|
|
81
|
-
## Async usage
|
|
82
|
-
|
|
83
|
-
`AsyncCortex` mirrors every method:
|
|
84
|
-
|
|
85
|
-
```python
|
|
86
|
-
import asyncio
|
|
87
|
-
from cortexdb import AsyncCortex
|
|
88
|
-
|
|
89
|
-
async def main():
|
|
90
|
-
async with AsyncCortex("http://localhost:3141") as c:
|
|
91
|
-
await c.experience("ws:demo", text="async memory works great")
|
|
92
|
-
pack = await c.recall("ws:demo", query="what works?")
|
|
93
|
-
print(pack["context_block"])
|
|
94
|
-
|
|
95
|
-
asyncio.run(main())
|
|
96
|
-
```
|
|
97
|
-
|
|
98
|
-
## Error handling
|
|
99
|
-
|
|
100
|
-
```python
|
|
101
|
-
from cortexdb import (
|
|
102
|
-
Cortex,
|
|
103
|
-
V1Error, # base
|
|
104
|
-
V1APIError, # non-2xx envelope
|
|
105
|
-
V1AuthError, # 401 / actor mismatch
|
|
106
|
-
V1PolicyDeniedError, # 403 — missing capability
|
|
107
|
-
V1RateLimitError, # 429 (carries retry_after)
|
|
108
|
-
V1NotConfiguredError,# 503 — feature not configured
|
|
109
|
-
V1ConnectionError,
|
|
110
|
-
V1TimeoutError,
|
|
111
|
-
)
|
|
112
|
-
|
|
113
|
-
with Cortex("http://localhost:3141") as c:
|
|
114
|
-
try:
|
|
115
|
-
c.experience("ws:demo", text="important data")
|
|
116
|
-
except V1RateLimitError as e:
|
|
117
|
-
print(f"rate limited; retry after {e.retry_after}s")
|
|
118
|
-
except V1PolicyDeniedError as e:
|
|
119
|
-
print(f"missing capability: {e}")
|
|
120
|
-
except V1APIError as e:
|
|
121
|
-
print(f"API error [{e.status_code}]: {e}")
|
|
122
|
-
```
|
|
123
|
-
|
|
124
|
-
## Constructor
|
|
125
|
-
|
|
126
|
-
| Parameter | Type | Default | Description |
|
|
127
|
-
|-----------|------|---------|-------------|
|
|
128
|
-
| `api_url` | `str` | `http://localhost:3141` | CortexDB v1 surface URL |
|
|
129
|
-
| `actor` | `str` | `user:default` | Sent as `X-Cortex-Actor`; must match the token subject when authed |
|
|
130
|
-
| `bearer` | `str \| None` | `None` | PASETO v4 public / JWT bearer (omit for auth-disabled dev) |
|
|
131
|
-
| `timeout` | `float` | `30.0` | Request timeout (seconds) |
|
|
132
|
-
|
|
133
|
-
## Links
|
|
134
|
-
|
|
135
|
-
- [Documentation](https://docs.cortexdb.ai)
|
|
136
|
-
- [Issue Tracker](https://github.com/cortexdb/cortexdb/issues)
|
|
137
|
-
|
|
138
|
-
## License
|
|
139
|
-
|
|
140
|
-
Apache-2.0
|
|
1
|
+
# CortexDB Python SDK
|
|
2
|
+
|
|
3
|
+
**The Long-Term Memory Layer for AI Systems.**
|
|
4
|
+
|
|
5
|
+
CortexDB gives your AI agents persistent, structured memory. Capture experiences, then recall a stratified pack (events, facts, beliefs, episodes, concepts) or get a grounded answer — all scoped to a hierarchical `scope` path.
|
|
6
|
+
|
|
7
|
+
[](https://pypi.org/project/cortexdbai/)
|
|
8
|
+
[](https://pypi.org/project/cortexdbai/)
|
|
9
|
+
[](https://github.com/cortexdb/cortexdb/blob/main/LICENSE)
|
|
10
|
+
|
|
11
|
+
This SDK targets the **v1 API** (`/v1/experience`, `/v1/recall`, `/v1/answer`, …), PASETO auth, and hierarchical scopes. The pre-0.3 `remember()`/`tenant_id` client was retired — `Cortex` is now an alias of `V1Client`.
|
|
12
|
+
|
|
13
|
+
## Installation
|
|
14
|
+
|
|
15
|
+
```bash
|
|
16
|
+
pip install cortexdbai
|
|
17
|
+
```
|
|
18
|
+
|
|
19
|
+
## Quick start
|
|
20
|
+
|
|
21
|
+
```python
|
|
22
|
+
from cortexdb import Cortex
|
|
23
|
+
|
|
24
|
+
# Local `docker run` with auth disabled (CORTEX_API_KEY unset on the server):
|
|
25
|
+
with Cortex("http://localhost:3141") as c:
|
|
26
|
+
c.experience("ws:demo", text="Priya at Acme signed for 200 seats. Q3 close.")
|
|
27
|
+
pack = c.recall("ws:demo", query="How many seats did Acme sign for?")
|
|
28
|
+
print(pack["context_block"])
|
|
29
|
+
```
|
|
30
|
+
|
|
31
|
+
### Hosted / multi-tenant (PASETO bearer + actor)
|
|
32
|
+
|
|
33
|
+
```python
|
|
34
|
+
with Cortex(
|
|
35
|
+
"https://api-v1.cortexdb.ai",
|
|
36
|
+
actor="user:alice",
|
|
37
|
+
bearer="v4.public…", # PASETO v4 public or JWT (RS256/ES256)
|
|
38
|
+
) as c:
|
|
39
|
+
out = c.answer(
|
|
40
|
+
"org:initech/user:alice",
|
|
41
|
+
"What did Alice say about coffee?",
|
|
42
|
+
)
|
|
43
|
+
print(out["answer"])
|
|
44
|
+
```
|
|
45
|
+
|
|
46
|
+
### One-call signup (no prior credentials)
|
|
47
|
+
|
|
48
|
+
```python
|
|
49
|
+
from cortexdb import Cortex
|
|
50
|
+
|
|
51
|
+
c = Cortex.signup() # POST /v1/auth/signup → free-tier PASETO
|
|
52
|
+
c.experience(c.actor, text="hello, memory!")
|
|
53
|
+
print(c.recall(c.actor, query="what did I say?")["context_block"])
|
|
54
|
+
```
|
|
55
|
+
|
|
56
|
+
## Core operations
|
|
57
|
+
|
|
58
|
+
```python
|
|
59
|
+
# Write — async by default (202); pass wait= for synchronous indexing.
|
|
60
|
+
c.experience("ws:demo", text="Deployed payments-service v3.1 to prod.")
|
|
61
|
+
c.experience("ws:demo", text="Rolled back auth-gateway.", wait="indexed")
|
|
62
|
+
|
|
63
|
+
# Recall — returns a StratifiedPack { context_block, layers, provenance }.
|
|
64
|
+
pack = c.recall("ws:demo", query="recent deploys", view="holistic")
|
|
65
|
+
|
|
66
|
+
# Answer — recall + LLM render with citations.
|
|
67
|
+
ans = c.answer("ws:demo", "What changed in payments recently?")
|
|
68
|
+
|
|
69
|
+
# Forget — GDPR erasure. confirm_all wipes the whole scope.
|
|
70
|
+
c.forget("ws:demo", confirm_all=True, cascade="redact_events",
|
|
71
|
+
audit_note="GDPR Article 17 request")
|
|
72
|
+
|
|
73
|
+
# Layer reads (paginated { items, has_more }).
|
|
74
|
+
c.events("ws:demo")
|
|
75
|
+
c.facts("ws:demo")
|
|
76
|
+
c.beliefs("ws:demo")
|
|
77
|
+
c.episodes("ws:demo")
|
|
78
|
+
c.understanding("ws:demo")
|
|
79
|
+
```
|
|
80
|
+
|
|
81
|
+
## Async usage
|
|
82
|
+
|
|
83
|
+
`AsyncCortex` mirrors every method:
|
|
84
|
+
|
|
85
|
+
```python
|
|
86
|
+
import asyncio
|
|
87
|
+
from cortexdb import AsyncCortex
|
|
88
|
+
|
|
89
|
+
async def main():
|
|
90
|
+
async with AsyncCortex("http://localhost:3141") as c:
|
|
91
|
+
await c.experience("ws:demo", text="async memory works great")
|
|
92
|
+
pack = await c.recall("ws:demo", query="what works?")
|
|
93
|
+
print(pack["context_block"])
|
|
94
|
+
|
|
95
|
+
asyncio.run(main())
|
|
96
|
+
```
|
|
97
|
+
|
|
98
|
+
## Error handling
|
|
99
|
+
|
|
100
|
+
```python
|
|
101
|
+
from cortexdb import (
|
|
102
|
+
Cortex,
|
|
103
|
+
V1Error, # base
|
|
104
|
+
V1APIError, # non-2xx envelope
|
|
105
|
+
V1AuthError, # 401 / actor mismatch
|
|
106
|
+
V1PolicyDeniedError, # 403 — missing capability
|
|
107
|
+
V1RateLimitError, # 429 (carries retry_after)
|
|
108
|
+
V1NotConfiguredError,# 503 — feature not configured
|
|
109
|
+
V1ConnectionError,
|
|
110
|
+
V1TimeoutError,
|
|
111
|
+
)
|
|
112
|
+
|
|
113
|
+
with Cortex("http://localhost:3141") as c:
|
|
114
|
+
try:
|
|
115
|
+
c.experience("ws:demo", text="important data")
|
|
116
|
+
except V1RateLimitError as e:
|
|
117
|
+
print(f"rate limited; retry after {e.retry_after}s")
|
|
118
|
+
except V1PolicyDeniedError as e:
|
|
119
|
+
print(f"missing capability: {e}")
|
|
120
|
+
except V1APIError as e:
|
|
121
|
+
print(f"API error [{e.status_code}]: {e}")
|
|
122
|
+
```
|
|
123
|
+
|
|
124
|
+
## Constructor
|
|
125
|
+
|
|
126
|
+
| Parameter | Type | Default | Description |
|
|
127
|
+
|-----------|------|---------|-------------|
|
|
128
|
+
| `api_url` | `str` | `http://localhost:3141` | CortexDB v1 surface URL |
|
|
129
|
+
| `actor` | `str` | `user:default` | Sent as `X-Cortex-Actor`; must match the token subject when authed |
|
|
130
|
+
| `bearer` | `str \| None` | `None` | PASETO v4 public / JWT bearer (omit for auth-disabled dev) |
|
|
131
|
+
| `timeout` | `float` | `30.0` | Request timeout (seconds) |
|
|
132
|
+
|
|
133
|
+
## Links
|
|
134
|
+
|
|
135
|
+
- [Documentation](https://docs.cortexdb.ai)
|
|
136
|
+
- [Issue Tracker](https://github.com/cortexdb/cortexdb/issues)
|
|
137
|
+
|
|
138
|
+
## License
|
|
139
|
+
|
|
140
|
+
Apache-2.0
|
|
@@ -1,71 +1,71 @@
|
|
|
1
|
-
"""CortexDB Python SDK — the long-term memory layer for AI systems.
|
|
2
|
-
|
|
3
|
-
The SDK is a thin HTTP client over the v1 API surface that cortexdb
|
|
4
|
-
exposes by default on port 3141. The top-level :class:`Cortex` class
|
|
5
|
-
(alias :class:`V1Client`) is what you should reach for.
|
|
6
|
-
|
|
7
|
-
Quick start::
|
|
8
|
-
|
|
9
|
-
from cortexdb import Cortex
|
|
10
|
-
|
|
11
|
-
# Local docker run with no auth (CORTEX_API_KEY unset on the server):
|
|
12
|
-
with Cortex("http://localhost:3141") as c:
|
|
13
|
-
c.experience("ws:demo", text="Priya at Acme signed for 200 seats.")
|
|
14
|
-
pack = c.recall("ws:demo", query="How many seats did Acme sign for?")
|
|
15
|
-
print(pack)
|
|
16
|
-
|
|
17
|
-
# Hosted / multi-tenant deployment with PASETO bearer + actor header:
|
|
18
|
-
with Cortex(
|
|
19
|
-
"https://api-v1.cortexdb.ai",
|
|
20
|
-
actor="user:alice",
|
|
21
|
-
bearer="eyJ...",
|
|
22
|
-
) as c:
|
|
23
|
-
out = c.answer(
|
|
24
|
-
"org:initech/user:alice",
|
|
25
|
-
question="What did Alice say about coffee?",
|
|
26
|
-
)
|
|
27
|
-
|
|
28
|
-
Versions ≤ 0.2.x exposed a separate ``cortexdb.Cortex`` class targeting
|
|
29
|
-
the legacy ``/v1/remember`` endpoints. That surface was retired in 0.3.0
|
|
30
|
-
because the cortexdb binary's public port now only serves the v1 API;
|
|
31
|
-
the legacy endpoints survive only as an internal bench-compat helper.
|
|
32
|
-
If you need them, pin ``cortexdbai<0.3``.
|
|
33
|
-
"""
|
|
34
|
-
|
|
35
|
-
from cortexdb.v1 import V1Client, AsyncV1Client
|
|
36
|
-
from cortexdb.v1.exceptions import (
|
|
37
|
-
V1APIError,
|
|
38
|
-
V1AuthError,
|
|
39
|
-
V1ConnectionError,
|
|
40
|
-
V1Error,
|
|
41
|
-
V1NotConfiguredError,
|
|
42
|
-
V1PolicyDeniedError,
|
|
43
|
-
V1RateLimitError,
|
|
44
|
-
V1TimeoutError,
|
|
45
|
-
)
|
|
46
|
-
from cortexdb import v1 # the explicit submodule namespace
|
|
47
|
-
|
|
48
|
-
# Ergonomic top-level aliases. New code can write either form.
|
|
49
|
-
Cortex = V1Client
|
|
50
|
-
AsyncCortex = AsyncV1Client
|
|
51
|
-
|
|
52
|
-
__version__ = "0.4.
|
|
53
|
-
__all__ = [
|
|
54
|
-
# Clients (preferred top-level names)
|
|
55
|
-
"Cortex",
|
|
56
|
-
"AsyncCortex",
|
|
57
|
-
# Explicit v1 names (identical classes, kept for code that pinned them)
|
|
58
|
-
"V1Client",
|
|
59
|
-
"AsyncV1Client",
|
|
60
|
-
# Submodule
|
|
61
|
-
"v1",
|
|
62
|
-
# Exceptions
|
|
63
|
-
"V1Error",
|
|
64
|
-
"V1APIError",
|
|
65
|
-
"V1AuthError",
|
|
66
|
-
"V1ConnectionError",
|
|
67
|
-
"V1TimeoutError",
|
|
68
|
-
"V1RateLimitError",
|
|
69
|
-
"V1NotConfiguredError",
|
|
70
|
-
"V1PolicyDeniedError",
|
|
71
|
-
]
|
|
1
|
+
"""CortexDB Python SDK — the long-term memory layer for AI systems.
|
|
2
|
+
|
|
3
|
+
The SDK is a thin HTTP client over the v1 API surface that cortexdb
|
|
4
|
+
exposes by default on port 3141. The top-level :class:`Cortex` class
|
|
5
|
+
(alias :class:`V1Client`) is what you should reach for.
|
|
6
|
+
|
|
7
|
+
Quick start::
|
|
8
|
+
|
|
9
|
+
from cortexdb import Cortex
|
|
10
|
+
|
|
11
|
+
# Local docker run with no auth (CORTEX_API_KEY unset on the server):
|
|
12
|
+
with Cortex("http://localhost:3141") as c:
|
|
13
|
+
c.experience("ws:demo", text="Priya at Acme signed for 200 seats.")
|
|
14
|
+
pack = c.recall("ws:demo", query="How many seats did Acme sign for?")
|
|
15
|
+
print(pack)
|
|
16
|
+
|
|
17
|
+
# Hosted / multi-tenant deployment with PASETO bearer + actor header:
|
|
18
|
+
with Cortex(
|
|
19
|
+
"https://api-v1.cortexdb.ai",
|
|
20
|
+
actor="user:alice",
|
|
21
|
+
bearer="eyJ...",
|
|
22
|
+
) as c:
|
|
23
|
+
out = c.answer(
|
|
24
|
+
"org:initech/user:alice",
|
|
25
|
+
question="What did Alice say about coffee?",
|
|
26
|
+
)
|
|
27
|
+
|
|
28
|
+
Versions ≤ 0.2.x exposed a separate ``cortexdb.Cortex`` class targeting
|
|
29
|
+
the legacy ``/v1/remember`` endpoints. That surface was retired in 0.3.0
|
|
30
|
+
because the cortexdb binary's public port now only serves the v1 API;
|
|
31
|
+
the legacy endpoints survive only as an internal bench-compat helper.
|
|
32
|
+
If you need them, pin ``cortexdbai<0.3``.
|
|
33
|
+
"""
|
|
34
|
+
|
|
35
|
+
from cortexdb.v1 import V1Client, AsyncV1Client
|
|
36
|
+
from cortexdb.v1.exceptions import (
|
|
37
|
+
V1APIError,
|
|
38
|
+
V1AuthError,
|
|
39
|
+
V1ConnectionError,
|
|
40
|
+
V1Error,
|
|
41
|
+
V1NotConfiguredError,
|
|
42
|
+
V1PolicyDeniedError,
|
|
43
|
+
V1RateLimitError,
|
|
44
|
+
V1TimeoutError,
|
|
45
|
+
)
|
|
46
|
+
from cortexdb import v1 # the explicit submodule namespace
|
|
47
|
+
|
|
48
|
+
# Ergonomic top-level aliases. New code can write either form.
|
|
49
|
+
Cortex = V1Client
|
|
50
|
+
AsyncCortex = AsyncV1Client
|
|
51
|
+
|
|
52
|
+
__version__ = "0.4.2"
|
|
53
|
+
__all__ = [
|
|
54
|
+
# Clients (preferred top-level names)
|
|
55
|
+
"Cortex",
|
|
56
|
+
"AsyncCortex",
|
|
57
|
+
# Explicit v1 names (identical classes, kept for code that pinned them)
|
|
58
|
+
"V1Client",
|
|
59
|
+
"AsyncV1Client",
|
|
60
|
+
# Submodule
|
|
61
|
+
"v1",
|
|
62
|
+
# Exceptions
|
|
63
|
+
"V1Error",
|
|
64
|
+
"V1APIError",
|
|
65
|
+
"V1AuthError",
|
|
66
|
+
"V1ConnectionError",
|
|
67
|
+
"V1TimeoutError",
|
|
68
|
+
"V1RateLimitError",
|
|
69
|
+
"V1NotConfiguredError",
|
|
70
|
+
"V1PolicyDeniedError",
|
|
71
|
+
]
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
"""CortexDB integration for AG2 (successor to AutoGen).
|
|
2
|
+
|
|
3
|
+
Provides a memory-augmented agent mixin and callable tools that connect
|
|
4
|
+
AG2's multi-agent framework to CortexDB's long-term memory system.
|
|
5
|
+
"""
|
|
6
|
+
|
|
7
|
+
from .agent import CortexDBAgent
|
|
8
|
+
from .tools import (
|
|
9
|
+
cortexdb_forget_fn,
|
|
10
|
+
cortexdb_search_fn,
|
|
11
|
+
cortexdb_store_fn,
|
|
12
|
+
register_cortexdb_tools,
|
|
13
|
+
)
|
|
14
|
+
|
|
15
|
+
__all__ = [
|
|
16
|
+
"CortexDBAgent",
|
|
17
|
+
"cortexdb_search_fn",
|
|
18
|
+
"cortexdb_store_fn",
|
|
19
|
+
"cortexdb_forget_fn",
|
|
20
|
+
"register_cortexdb_tools",
|
|
21
|
+
]
|
|
@@ -0,0 +1,183 @@
|
|
|
1
|
+
"""AG2 agent with built-in CortexDB memory.
|
|
2
|
+
|
|
3
|
+
Provides a ConversableAgent subclass that automatically stores
|
|
4
|
+
conversation turns and retrieves relevant context from CortexDB
|
|
5
|
+
before generating responses. Compatible with AG2 (the successor
|
|
6
|
+
to Microsoft AutoGen).
|
|
7
|
+
"""
|
|
8
|
+
|
|
9
|
+
from __future__ import annotations
|
|
10
|
+
|
|
11
|
+
from typing import Any, Optional, Union
|
|
12
|
+
|
|
13
|
+
from autogen import ConversableAgent
|
|
14
|
+
|
|
15
|
+
from cortexdb import Cortex
|
|
16
|
+
|
|
17
|
+
|
|
18
|
+
class CortexDBAgent(ConversableAgent):
|
|
19
|
+
"""AG2 ConversableAgent with automatic CortexDB memory integration.
|
|
20
|
+
|
|
21
|
+
Extends AG2's ConversableAgent to automatically store conversation
|
|
22
|
+
turns in CortexDB and retrieve relevant past context before generating
|
|
23
|
+
responses. This enables the agent to maintain long-term memory across
|
|
24
|
+
conversations and sessions.
|
|
25
|
+
|
|
26
|
+
The agent injects retrieved context as a system-level prefix to the
|
|
27
|
+
conversation, giving the LLM access to relevant memories without
|
|
28
|
+
modifying the visible chat history.
|
|
29
|
+
|
|
30
|
+
Args:
|
|
31
|
+
name: The agent's name.
|
|
32
|
+
cortex_client: An initialized CortexDB client instance.
|
|
33
|
+
scope: The hierarchical scope path for memory isolation.
|
|
34
|
+
auto_store: Whether to automatically store conversation turns.
|
|
35
|
+
Defaults to ``True``.
|
|
36
|
+
auto_recall: Whether to automatically retrieve context before
|
|
37
|
+
responding. Defaults to ``True``.
|
|
38
|
+
**kwargs: Additional keyword arguments passed to ConversableAgent.
|
|
39
|
+
|
|
40
|
+
Example::
|
|
41
|
+
|
|
42
|
+
from cortexdb import Cortex
|
|
43
|
+
from cortexdb_ag2 import CortexDBAgent
|
|
44
|
+
|
|
45
|
+
client = Cortex("http://localhost:3141")
|
|
46
|
+
agent = CortexDBAgent(
|
|
47
|
+
name="memory_assistant",
|
|
48
|
+
cortex_client=client,
|
|
49
|
+
scope="user:default",
|
|
50
|
+
llm_config=llm_config,
|
|
51
|
+
system_message="You are a helpful assistant with long-term memory.",
|
|
52
|
+
)
|
|
53
|
+
"""
|
|
54
|
+
|
|
55
|
+
def __init__(
|
|
56
|
+
self,
|
|
57
|
+
name: str,
|
|
58
|
+
cortex_client: Cortex,
|
|
59
|
+
scope: str = "user:default",
|
|
60
|
+
auto_store: bool = True,
|
|
61
|
+
auto_recall: bool = True,
|
|
62
|
+
**kwargs: Any,
|
|
63
|
+
) -> None:
|
|
64
|
+
super().__init__(name=name, **kwargs)
|
|
65
|
+
self._cortex_client = cortex_client
|
|
66
|
+
self._scope = scope
|
|
67
|
+
self._auto_store = auto_store
|
|
68
|
+
self._auto_recall = auto_recall
|
|
69
|
+
|
|
70
|
+
def generate_reply(
|
|
71
|
+
self,
|
|
72
|
+
messages: Optional[list[dict[str, Any]]] = None,
|
|
73
|
+
sender: Optional[Any] = None,
|
|
74
|
+
**kwargs: Any,
|
|
75
|
+
) -> Union[str, dict[str, Any], None]:
|
|
76
|
+
"""Generate a reply with CortexDB memory augmentation.
|
|
77
|
+
|
|
78
|
+
Before generating a reply, retrieves relevant context from CortexDB
|
|
79
|
+
based on the latest message. After generating, stores the conversation
|
|
80
|
+
turn for future recall.
|
|
81
|
+
|
|
82
|
+
Args:
|
|
83
|
+
messages: The conversation messages to respond to.
|
|
84
|
+
sender: The agent that sent the message.
|
|
85
|
+
**kwargs: Additional keyword arguments.
|
|
86
|
+
|
|
87
|
+
Returns:
|
|
88
|
+
The generated reply string, a structured reply dict, or None.
|
|
89
|
+
"""
|
|
90
|
+
if messages and self._auto_recall:
|
|
91
|
+
latest_message = messages[-1]
|
|
92
|
+
content = latest_message.get("content", "")
|
|
93
|
+
if content:
|
|
94
|
+
context = self._recall_context(str(content))
|
|
95
|
+
if context:
|
|
96
|
+
messages = self._inject_memory_context(messages, context)
|
|
97
|
+
|
|
98
|
+
reply = super().generate_reply(messages=messages, sender=sender, **kwargs)
|
|
99
|
+
|
|
100
|
+
if reply and self._auto_store and messages:
|
|
101
|
+
latest_content = messages[-1].get("content", "") if messages else ""
|
|
102
|
+
reply_text = reply if isinstance(reply, str) else reply.get("content", "")
|
|
103
|
+
if latest_content and reply_text:
|
|
104
|
+
self._store_turn(str(latest_content), str(reply_text))
|
|
105
|
+
|
|
106
|
+
return reply
|
|
107
|
+
|
|
108
|
+
def _recall_context(self, query: str) -> str:
|
|
109
|
+
"""Retrieve relevant context from CortexDB.
|
|
110
|
+
|
|
111
|
+
Args:
|
|
112
|
+
query: The query to search for relevant memories.
|
|
113
|
+
|
|
114
|
+
Returns:
|
|
115
|
+
The context string from CortexDB, or empty string on failure.
|
|
116
|
+
"""
|
|
117
|
+
try:
|
|
118
|
+
result = self._cortex_client.recall(
|
|
119
|
+
self._scope,
|
|
120
|
+
query=query,
|
|
121
|
+
)
|
|
122
|
+
except Exception:
|
|
123
|
+
return ""
|
|
124
|
+
|
|
125
|
+
return result.get("context_block", "") if result else ""
|
|
126
|
+
|
|
127
|
+
def _store_turn(self, user_message: str, assistant_reply: str) -> None:
|
|
128
|
+
"""Store a conversation turn in CortexDB.
|
|
129
|
+
|
|
130
|
+
Args:
|
|
131
|
+
user_message: The user's message.
|
|
132
|
+
assistant_reply: The agent's reply.
|
|
133
|
+
"""
|
|
134
|
+
content = f"User: {user_message}\nAssistant: {assistant_reply}"
|
|
135
|
+
try:
|
|
136
|
+
self._cortex_client.experience(self._scope, text=content)
|
|
137
|
+
except Exception:
|
|
138
|
+
pass
|
|
139
|
+
|
|
140
|
+
def _inject_memory_context(
|
|
141
|
+
self,
|
|
142
|
+
messages: list[dict[str, Any]],
|
|
143
|
+
context: str,
|
|
144
|
+
) -> list[dict[str, Any]]:
|
|
145
|
+
"""Inject retrieved memory context into the message list.
|
|
146
|
+
|
|
147
|
+
Prepends a system message containing the retrieved context
|
|
148
|
+
so the LLM can reference it when generating a response.
|
|
149
|
+
|
|
150
|
+
Args:
|
|
151
|
+
messages: The original conversation messages.
|
|
152
|
+
context: The retrieved context string from CortexDB.
|
|
153
|
+
|
|
154
|
+
Returns:
|
|
155
|
+
A new message list with the memory context injected.
|
|
156
|
+
"""
|
|
157
|
+
context_message = {
|
|
158
|
+
"role": "system",
|
|
159
|
+
"content": (
|
|
160
|
+
f"Relevant context from long-term memory:\n\n{context}\n\n"
|
|
161
|
+
"Use this context to inform your response if relevant."
|
|
162
|
+
),
|
|
163
|
+
}
|
|
164
|
+
|
|
165
|
+
augmented = list(messages)
|
|
166
|
+
augmented.insert(0, context_message)
|
|
167
|
+
return augmented
|
|
168
|
+
|
|
169
|
+
def clear_memory(self) -> dict[str, Any]:
|
|
170
|
+
"""Clear all memories for this agent's scope.
|
|
171
|
+
|
|
172
|
+
Removes all stored memories from CortexDB for the configured
|
|
173
|
+
scope path.
|
|
174
|
+
|
|
175
|
+
Returns:
|
|
176
|
+
The forget response dict from CortexDB.
|
|
177
|
+
"""
|
|
178
|
+
return self._cortex_client.forget(
|
|
179
|
+
self._scope,
|
|
180
|
+
confirm_all=True,
|
|
181
|
+
cascade="redact_events",
|
|
182
|
+
reason="AG2 agent memory clear requested",
|
|
183
|
+
)
|