cortexdbai 0.8.0__tar.gz → 0.10.0__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.
Files changed (95) hide show
  1. {cortexdbai-0.8.0 → cortexdbai-0.10.0}/PKG-INFO +1 -1
  2. {cortexdbai-0.8.0 → cortexdbai-0.10.0}/cortexdb/__init__.py +71 -71
  3. {cortexdbai-0.8.0 → cortexdbai-0.10.0}/cortexdb/v1/client.py +51 -15
  4. {cortexdbai-0.8.0 → cortexdbai-0.10.0}/pyproject.toml +186 -186
  5. {cortexdbai-0.8.0 → cortexdbai-0.10.0}/.gitignore +0 -0
  6. {cortexdbai-0.8.0 → cortexdbai-0.10.0}/README.md +0 -0
  7. {cortexdbai-0.8.0 → cortexdbai-0.10.0}/cortexdb/integrations/__init__.py +0 -0
  8. {cortexdbai-0.8.0 → cortexdbai-0.10.0}/cortexdb/integrations/ag2/__init__.py +0 -0
  9. {cortexdbai-0.8.0 → cortexdbai-0.10.0}/cortexdb/integrations/ag2/agent.py +0 -0
  10. {cortexdbai-0.8.0 → cortexdbai-0.10.0}/cortexdb/integrations/ag2/tools.py +0 -0
  11. {cortexdbai-0.8.0 → cortexdbai-0.10.0}/cortexdb/integrations/agno/__init__.py +0 -0
  12. {cortexdbai-0.8.0 → cortexdbai-0.10.0}/cortexdb/integrations/agno/memory.py +0 -0
  13. {cortexdbai-0.8.0 → cortexdbai-0.10.0}/cortexdb/integrations/agno/tools.py +0 -0
  14. {cortexdbai-0.8.0 → cortexdbai-0.10.0}/cortexdb/integrations/autogen/__init__.py +0 -0
  15. {cortexdbai-0.8.0 → cortexdbai-0.10.0}/cortexdb/integrations/autogen/agent.py +0 -0
  16. {cortexdbai-0.8.0 → cortexdbai-0.10.0}/cortexdb/integrations/autogen/tools.py +0 -0
  17. {cortexdbai-0.8.0 → cortexdbai-0.10.0}/cortexdb/integrations/beeai/__init__.py +0 -0
  18. {cortexdbai-0.8.0 → cortexdbai-0.10.0}/cortexdb/integrations/beeai/memory.py +0 -0
  19. {cortexdbai-0.8.0 → cortexdbai-0.10.0}/cortexdb/integrations/beeai/tools.py +0 -0
  20. {cortexdbai-0.8.0 → cortexdbai-0.10.0}/cortexdb/integrations/camel/__init__.py +0 -0
  21. {cortexdbai-0.8.0 → cortexdbai-0.10.0}/cortexdb/integrations/camel/memory.py +0 -0
  22. {cortexdbai-0.8.0 → cortexdbai-0.10.0}/cortexdb/integrations/camel/tools.py +0 -0
  23. {cortexdbai-0.8.0 → cortexdbai-0.10.0}/cortexdb/integrations/controlflow/__init__.py +0 -0
  24. {cortexdbai-0.8.0 → cortexdbai-0.10.0}/cortexdb/integrations/controlflow/memory.py +0 -0
  25. {cortexdbai-0.8.0 → cortexdbai-0.10.0}/cortexdb/integrations/crewai/__init__.py +0 -0
  26. {cortexdbai-0.8.0 → cortexdbai-0.10.0}/cortexdb/integrations/crewai/memory.py +0 -0
  27. {cortexdbai-0.8.0 → cortexdbai-0.10.0}/cortexdb/integrations/crewai/tools.py +0 -0
  28. {cortexdbai-0.8.0 → cortexdbai-0.10.0}/cortexdb/integrations/deepinfra/__init__.py +0 -0
  29. {cortexdbai-0.8.0 → cortexdbai-0.10.0}/cortexdb/integrations/deepinfra/config.py +0 -0
  30. {cortexdbai-0.8.0 → cortexdbai-0.10.0}/cortexdb/integrations/deepinfra/embeddings.py +0 -0
  31. {cortexdbai-0.8.0 → cortexdbai-0.10.0}/cortexdb/integrations/deepinfra/openai_compat.py +0 -0
  32. {cortexdbai-0.8.0 → cortexdbai-0.10.0}/cortexdb/integrations/dify/__init__.py +0 -0
  33. {cortexdbai-0.8.0 → cortexdbai-0.10.0}/cortexdb/integrations/dify/manifest.yaml +0 -0
  34. {cortexdbai-0.8.0 → cortexdbai-0.10.0}/cortexdb/integrations/dify/tool.py +0 -0
  35. {cortexdbai-0.8.0 → cortexdbai-0.10.0}/cortexdb/integrations/dspy/__init__.py +0 -0
  36. {cortexdbai-0.8.0 → cortexdbai-0.10.0}/cortexdb/integrations/dspy/memory.py +0 -0
  37. {cortexdbai-0.8.0 → cortexdbai-0.10.0}/cortexdb/integrations/dspy/retriever.py +0 -0
  38. {cortexdbai-0.8.0 → cortexdbai-0.10.0}/cortexdb/integrations/fireworks/__init__.py +0 -0
  39. {cortexdbai-0.8.0 → cortexdbai-0.10.0}/cortexdb/integrations/fireworks/config.py +0 -0
  40. {cortexdbai-0.8.0 → cortexdbai-0.10.0}/cortexdb/integrations/fireworks/embeddings.py +0 -0
  41. {cortexdbai-0.8.0 → cortexdbai-0.10.0}/cortexdb/integrations/fireworks/openai_compat.py +0 -0
  42. {cortexdbai-0.8.0 → cortexdbai-0.10.0}/cortexdb/integrations/flowise/__init__.py +0 -0
  43. {cortexdbai-0.8.0 → cortexdbai-0.10.0}/cortexdb/integrations/flowise/node.py +0 -0
  44. {cortexdbai-0.8.0 → cortexdbai-0.10.0}/cortexdb/integrations/google_adk/__init__.py +0 -0
  45. {cortexdbai-0.8.0 → cortexdbai-0.10.0}/cortexdb/integrations/google_adk/tools.py +0 -0
  46. {cortexdbai-0.8.0 → cortexdbai-0.10.0}/cortexdb/integrations/groq/__init__.py +0 -0
  47. {cortexdbai-0.8.0 → cortexdbai-0.10.0}/cortexdb/integrations/groq/config.py +0 -0
  48. {cortexdbai-0.8.0 → cortexdbai-0.10.0}/cortexdb/integrations/groq/embeddings.py +0 -0
  49. {cortexdbai-0.8.0 → cortexdbai-0.10.0}/cortexdb/integrations/groq/openai_compat.py +0 -0
  50. {cortexdbai-0.8.0 → cortexdbai-0.10.0}/cortexdb/integrations/hermes/__init__.py +0 -0
  51. {cortexdbai-0.8.0 → cortexdbai-0.10.0}/cortexdb/integrations/hermes/provider.py +0 -0
  52. {cortexdbai-0.8.0 → cortexdbai-0.10.0}/cortexdb/integrations/instructor/__init__.py +0 -0
  53. {cortexdbai-0.8.0 → cortexdbai-0.10.0}/cortexdb/integrations/instructor/memory.py +0 -0
  54. {cortexdbai-0.8.0 → cortexdbai-0.10.0}/cortexdb/integrations/langchain/__init__.py +0 -0
  55. {cortexdbai-0.8.0 → cortexdbai-0.10.0}/cortexdb/integrations/langchain/memory.py +0 -0
  56. {cortexdbai-0.8.0 → cortexdbai-0.10.0}/cortexdb/integrations/langchain/retriever.py +0 -0
  57. {cortexdbai-0.8.0 → cortexdbai-0.10.0}/cortexdb/integrations/langchain/tools.py +0 -0
  58. {cortexdbai-0.8.0 → cortexdbai-0.10.0}/cortexdb/integrations/langgraph/__init__.py +0 -0
  59. {cortexdbai-0.8.0 → cortexdbai-0.10.0}/cortexdb/integrations/langgraph/memory.py +0 -0
  60. {cortexdbai-0.8.0 → cortexdbai-0.10.0}/cortexdb/integrations/letta/__init__.py +0 -0
  61. {cortexdbai-0.8.0 → cortexdbai-0.10.0}/cortexdb/integrations/letta/storage.py +0 -0
  62. {cortexdbai-0.8.0 → cortexdbai-0.10.0}/cortexdb/integrations/llamaindex/__init__.py +0 -0
  63. {cortexdbai-0.8.0 → cortexdbai-0.10.0}/cortexdb/integrations/llamaindex/memory.py +0 -0
  64. {cortexdbai-0.8.0 → cortexdbai-0.10.0}/cortexdb/integrations/nemo_guardrails/__init__.py +0 -0
  65. {cortexdbai-0.8.0 → cortexdbai-0.10.0}/cortexdb/integrations/nemo_guardrails/actions.py +0 -0
  66. {cortexdbai-0.8.0 → cortexdbai-0.10.0}/cortexdb/integrations/nemo_guardrails/knowledge_base.py +0 -0
  67. {cortexdbai-0.8.0 → cortexdbai-0.10.0}/cortexdb/integrations/ollama/__init__.py +0 -0
  68. {cortexdbai-0.8.0 → cortexdbai-0.10.0}/cortexdb/integrations/ollama/config.py +0 -0
  69. {cortexdbai-0.8.0 → cortexdbai-0.10.0}/cortexdb/integrations/ollama/embeddings.py +0 -0
  70. {cortexdbai-0.8.0 → cortexdbai-0.10.0}/cortexdb/integrations/openai_agents/__init__.py +0 -0
  71. {cortexdbai-0.8.0 → cortexdbai-0.10.0}/cortexdb/integrations/openai_agents/tools.py +0 -0
  72. {cortexdbai-0.8.0 → cortexdbai-0.10.0}/cortexdb/integrations/prefect/__init__.py +0 -0
  73. {cortexdbai-0.8.0 → cortexdbai-0.10.0}/cortexdb/integrations/prefect/blocks.py +0 -0
  74. {cortexdbai-0.8.0 → cortexdbai-0.10.0}/cortexdb/integrations/prefect/tasks.py +0 -0
  75. {cortexdbai-0.8.0 → cortexdbai-0.10.0}/cortexdb/integrations/pydanticai/__init__.py +0 -0
  76. {cortexdbai-0.8.0 → cortexdbai-0.10.0}/cortexdb/integrations/pydanticai/dependencies.py +0 -0
  77. {cortexdbai-0.8.0 → cortexdbai-0.10.0}/cortexdb/integrations/pydanticai/tools.py +0 -0
  78. {cortexdbai-0.8.0 → cortexdbai-0.10.0}/cortexdb/integrations/smolagents/__init__.py +0 -0
  79. {cortexdbai-0.8.0 → cortexdbai-0.10.0}/cortexdb/integrations/smolagents/tools.py +0 -0
  80. {cortexdbai-0.8.0 → cortexdbai-0.10.0}/cortexdb/integrations/temporal/__init__.py +0 -0
  81. {cortexdbai-0.8.0 → cortexdbai-0.10.0}/cortexdb/integrations/temporal/activities.py +0 -0
  82. {cortexdbai-0.8.0 → cortexdbai-0.10.0}/cortexdb/integrations/temporal/interceptor.py +0 -0
  83. {cortexdbai-0.8.0 → cortexdbai-0.10.0}/cortexdb/integrations/together/__init__.py +0 -0
  84. {cortexdbai-0.8.0 → cortexdbai-0.10.0}/cortexdb/integrations/together/config.py +0 -0
  85. {cortexdbai-0.8.0 → cortexdbai-0.10.0}/cortexdb/integrations/together/embeddings.py +0 -0
  86. {cortexdbai-0.8.0 → cortexdbai-0.10.0}/cortexdb/integrations/together/openai_compat.py +0 -0
  87. {cortexdbai-0.8.0 → cortexdbai-0.10.0}/cortexdb/integrations/vllm/__init__.py +0 -0
  88. {cortexdbai-0.8.0 → cortexdbai-0.10.0}/cortexdb/integrations/vllm/config.py +0 -0
  89. {cortexdbai-0.8.0 → cortexdbai-0.10.0}/cortexdb/integrations/vllm/embeddings.py +0 -0
  90. {cortexdbai-0.8.0 → cortexdbai-0.10.0}/cortexdb/integrations/vllm/openai_compat.py +0 -0
  91. {cortexdbai-0.8.0 → cortexdbai-0.10.0}/cortexdb/py.typed +0 -0
  92. {cortexdbai-0.8.0 → cortexdbai-0.10.0}/cortexdb/v1/__init__.py +0 -0
  93. {cortexdbai-0.8.0 → cortexdbai-0.10.0}/cortexdb/v1/exceptions.py +0 -0
  94. {cortexdbai-0.8.0 → cortexdbai-0.10.0}/tests/__init__.py +0 -0
  95. {cortexdbai-0.8.0 → cortexdbai-0.10.0}/tests/test_conflicts.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: cortexdbai
3
- Version: 0.8.0
3
+ Version: 0.10.0
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
@@ -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.8.0"
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.10.0"
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
+ ]
@@ -104,19 +104,31 @@ def _envelope(
104
104
  observed_actor: Optional[Mapping[str, str]] = None,
105
105
  blob_id: Optional[str] = None,
106
106
  transcript: Optional[str] = None,
107
+ triple: Optional[Mapping[str, Any]] = None,
107
108
  ) -> dict:
108
109
  """Build a v1 ``ExperienceEnvelope`` for the bulk-ingest endpoint.
109
110
 
110
- Exactly one of ``text`` / ``json_data`` / ``blob_id`` must be provided
111
- (Message, Json, or BlobRef content kinds). With ``blob_id`` you may also
112
- pass ``transcript`` — the text you already have for that object — and the
113
- server will index it and SKIP the content processor (no re-transcription /
114
- OCR). Defaults are filled in for ``observed_at`` (current UTC) and
111
+ Exactly one of ``text`` / ``json_data`` / ``blob_id`` / ``triple`` must be
112
+ provided (Message, Json, BlobRef, or Triple content kinds). With
113
+ ``blob_id`` you may also pass ``transcript`` — the text you already have
114
+ for that object — and the server will index it and SKIP the content
115
+ processor (no re-transcription / OCR). A ``triple`` writes a fact
116
+ DETERMINISTICALLY (no LLM extractor in the loop, server >= v0.7.0):
117
+ ``{"subject": {"type": "literal", "datatype": "string", "value": "Acme"},
118
+ "predicate": "billing_contact",
119
+ "object": {"type": "literal", "datatype": "string", "value": "Dana"}}``
120
+ (subject/object may also be ``{"type": "entity", "id": ...}`` or
121
+ ``{"type": "concept", "id": ...}``; the server canonicalizes the
122
+ predicate). Defaults are filled in for ``observed_at`` (current UTC) and
115
123
  ``idempotency_key`` (UUID v4).
116
124
  """
117
- if sum(x is not None for x in (text, json_data, blob_id)) != 1:
118
- raise ValueError("provide exactly one of `text`, `json_data`, or `blob_id`")
119
- if blob_id is not None:
125
+ if sum(x is not None for x in (text, json_data, blob_id, triple)) != 1:
126
+ raise ValueError(
127
+ "provide exactly one of `text`, `json_data`, `blob_id`, or `triple`"
128
+ )
129
+ if triple is not None:
130
+ content: dict = {"kind": "triple", "triple": dict(triple)}
131
+ elif blob_id is not None:
120
132
  content = {"kind": "blob_ref", "blob_id": blob_id}
121
133
  if transcript is not None:
122
134
  content["transcript"] = transcript
@@ -363,13 +375,16 @@ class V1Client:
363
375
  wait: Optional[str] = None,
364
376
  blob_id: Optional[str] = None,
365
377
  transcript: Optional[str] = None,
378
+ triple: Optional[Mapping[str, Any]] = None,
366
379
  ) -> dict:
367
380
  """``POST /v1/experience`` — single envelope. Provide exactly one of
368
- ``text`` / ``json_data`` / ``blob_id``. With ``blob_id`` (from
369
- :meth:`upload_blob`) the referenced file is processed into text; pass
370
- ``transcript`` to supply your own text instead and skip the processor.
371
- ``wait`` selects sync semantics: ``captured``, ``indexed``,
372
- ``consolidated``."""
381
+ ``text`` / ``json_data`` / ``blob_id`` / ``triple``. With ``blob_id``
382
+ (from :meth:`upload_blob`) the referenced file is processed into text;
383
+ pass ``transcript`` to supply your own text instead and skip the
384
+ processor. A ``triple`` (subject/predicate/object dict, see
385
+ :func:`_envelope`) writes a fact deterministically — no LLM extractor
386
+ in the loop (server >= v0.7.0). ``wait`` selects sync semantics:
387
+ ``captured``, ``indexed``, ``consolidated``."""
373
388
  env = _envelope(
374
389
  scope,
375
390
  role=role,
@@ -380,6 +395,7 @@ class V1Client:
380
395
  idempotency_key=idempotency_key,
381
396
  blob_id=blob_id,
382
397
  transcript=transcript,
398
+ triple=triple,
383
399
  )
384
400
  path = "/v1/experience" + (f"?wait={wait}" if wait else "")
385
401
  return self._post(path, env)
@@ -453,6 +469,7 @@ class V1Client:
453
469
  observed_at=item.get("observed_at"),
454
470
  idempotency_key=item.get("idempotency_key"),
455
471
  observed_actor=item.get("observed_actor"),
472
+ triple=item.get("triple"),
456
473
  )
457
474
  for item in items
458
475
  ]
@@ -471,9 +488,16 @@ class V1Client:
471
488
  diagnostics: str = "none",
472
489
  budgets: Optional[Mapping[str, Any]] = None,
473
490
  temporal: Optional[Mapping[str, Any]] = None,
491
+ filters: Optional[Mapping[str, Any]] = None,
474
492
  ) -> dict:
475
493
  """``POST /v1/recall`` — returns a ``StratifiedPack``.
476
494
 
495
+ ``filters`` — hard eligibility predicates over stored event
496
+ attributes: ``{"metadata": {"labels": "primary_inbox"}}`` keeps only
497
+ events whose labels contain the value (lists mean any-of). Valid
498
+ keys: labels, intent, modality, caller, observed_actor; unknown
499
+ keys 422. Relevance decides order; filters decide eligibility.
500
+
477
501
  ``diagnostics`` defaults to ``"none"`` so free-tier tokens — which
478
502
  do not carry the ``diagnostics.read`` capability — succeed on the
479
503
  first call. Pass ``diagnostics="summary"`` (or ``"full"``) when
@@ -486,6 +510,8 @@ class V1Client:
486
510
  body["include"] = list(include)
487
511
  if budgets:
488
512
  body["budgets"] = dict(budgets)
513
+ if filters:
514
+ body["filters"] = dict(filters)
489
515
  if temporal:
490
516
  body["temporal"] = dict(temporal)
491
517
  return self._post("/v1/recall", body)
@@ -505,6 +531,7 @@ class V1Client:
505
531
  use_pack_id: Optional[str] = None,
506
532
  temporal: Optional[Mapping[str, Any]] = None,
507
533
  diagnostics: str = "none",
534
+ filters: Optional[Mapping[str, Any]] = None,
508
535
  ) -> dict:
509
536
  """``POST /v1/answer`` — runs recall + LLM render.
510
537
 
@@ -541,6 +568,8 @@ class V1Client:
541
568
  body["use_pack_id"] = use_pack_id
542
569
  if temporal:
543
570
  body["temporal"] = dict(temporal)
571
+ if filters:
572
+ body["filters"] = dict(filters)
544
573
  return self._post("/v1/answer", body)
545
574
 
546
575
  def compose(
@@ -559,6 +588,7 @@ class V1Client:
559
588
  model: Optional[str] = None,
560
589
  use_pack_id: Optional[str] = None,
561
590
  include_context: bool = False,
591
+ filters: Optional[Mapping[str, Any]] = None,
562
592
  ) -> dict:
563
593
  """``POST /v1/compose`` — produce a structured markdown DOCUMENT
564
594
  from memory (digests, reports, overviews).
@@ -600,6 +630,8 @@ class V1Client:
600
630
  body["use_pack_id"] = use_pack_id
601
631
  if include_context:
602
632
  body["include_context"] = True
633
+ if filters:
634
+ body["filters"] = dict(filters)
603
635
  return self._post("/v1/compose", body)
604
636
 
605
637
  # ── layer reads ───────────────────────────────────────────────────
@@ -1013,6 +1045,7 @@ class AsyncV1Client:
1013
1045
  observed_at=item.get("observed_at"),
1014
1046
  idempotency_key=item.get("idempotency_key"),
1015
1047
  observed_actor=item.get("observed_actor"),
1048
+ triple=item.get("triple"),
1016
1049
  )
1017
1050
  for item in items
1018
1051
  ]
@@ -1031,11 +1064,13 @@ class AsyncV1Client:
1031
1064
  wait: Optional[str] = None,
1032
1065
  blob_id: Optional[str] = None,
1033
1066
  transcript: Optional[str] = None,
1067
+ triple: Optional[Mapping[str, Any]] = None,
1034
1068
  ) -> dict:
1035
1069
  """``POST /v1/experience``. Provide exactly one of ``text`` /
1036
- ``json_data`` / ``blob_id``. With ``blob_id`` (from
1070
+ ``json_data`` / ``blob_id`` / ``triple``. With ``blob_id`` (from
1037
1071
  :meth:`upload_blob`), pass ``transcript`` to index your own text and
1038
- skip server-side extraction."""
1072
+ skip server-side extraction. A ``triple`` writes a fact
1073
+ deterministically — no LLM extractor in the loop (server >= v0.7.0)."""
1039
1074
  env = _envelope(
1040
1075
  scope,
1041
1076
  role=role,
@@ -1046,6 +1081,7 @@ class AsyncV1Client:
1046
1081
  idempotency_key=idempotency_key,
1047
1082
  blob_id=blob_id,
1048
1083
  transcript=transcript,
1084
+ triple=triple,
1049
1085
  )
1050
1086
  path = "/v1/experience" + (f"?wait={wait}" if wait else "")
1051
1087
  return await self._post(path, env)
@@ -1,186 +1,186 @@
1
- [build-system]
2
- requires = ["hatchling"]
3
- build-backend = "hatchling.build"
4
-
5
- [project]
6
- name = "cortexdbai"
7
- version = "0.8.0"
8
- description = "The Long-Term Memory Layer for AI Systems"
9
- readme = "README.md"
10
- license = "Apache-2.0"
11
- # 3.10+: the v1 module uses PEP 604 unions (`str | None`) in TypedDict
12
- # field annotations, which Python 3.9 cannot evaluate at class-definition
13
- # time even with `from __future__ import annotations`. Python 3.9 hit
14
- # end-of-life on 2025-10-31. Declaring >=3.10 means `pip install
15
- # cortexdbai` on 3.9 fails immediately with a clear "requires Python
16
- # 3.10+" error from pip — not a silent install followed by an obscure
17
- # `TypeError: Unable to evaluate type annotation 'str | None'` on the
18
- # first import.
19
- requires-python = ">=3.10"
20
- authors = [
21
- { name = "Prashant Malik", email = "prashant@cortexdb.ai" },
22
- ]
23
- keywords = ["ai", "memory", "llm", "knowledge-graph", "event-sourcing", "cortexdb"]
24
- classifiers = [
25
- "Development Status :: 4 - Beta",
26
- "Intended Audience :: Developers",
27
- "Programming Language :: Python :: 3",
28
- "Programming Language :: Python :: 3.10",
29
- "Programming Language :: Python :: 3.11",
30
- "Programming Language :: Python :: 3.12",
31
- "Programming Language :: Python :: 3.13",
32
- "Topic :: Scientific/Engineering :: Artificial Intelligence",
33
- "Topic :: Database",
34
- "Typing :: Typed",
35
- ]
36
- dependencies = [
37
- "requests>=2.31",
38
- "httpx>=0.24",
39
- "pydantic>=2.0",
40
- "tenacity>=8.0",
41
- ]
42
-
43
- [project.optional-dependencies]
44
- async = [
45
- "httpx[http2]",
46
- ]
47
- dev = [
48
- "pytest>=8.0",
49
- "pytest-asyncio>=0.23",
50
- "ruff>=0.4",
51
- ]
52
-
53
- # --- Framework / provider integrations -------------------------------------
54
- # Each extra pulls in only the third-party framework needed by the matching
55
- # submodule under `cortexdb.integrations.<name>`. The CortexDB client itself
56
- # is always the base package, so it is never listed here. Nothing under
57
- # `cortexdb.integrations` is imported at `import cortexdb` time — importing a
58
- # submodule without its extra raises a clean ModuleNotFoundError.
59
- autogen = [
60
- "ag2>=0.4",
61
- ]
62
- ag2 = [
63
- "ag2>=0.4",
64
- ]
65
- agno = [
66
- "agno>=1.0",
67
- ]
68
- langchain = [
69
- "langchain-core>=0.3",
70
- ]
71
- beeai = [
72
- "beeai-framework>=0.1",
73
- ]
74
- camel = [
75
- "camel-ai>=0.2",
76
- ]
77
- controlflow = [
78
- "controlflow>=0.11",
79
- ]
80
- crewai = [
81
- "crewai>=0.80",
82
- ]
83
- dify = []
84
- dspy = [
85
- "dspy>=2.0",
86
- ]
87
- flowise = []
88
- google-adk = [
89
- "google-adk>=0.1",
90
- ]
91
- hermes = []
92
- instructor = [
93
- "instructor>=1.0",
94
- "pydantic>=2.0",
95
- ]
96
- langgraph = [
97
- "langchain-core>=0.3",
98
- "langgraph-checkpoint>=2.0",
99
- ]
100
- letta = [
101
- "letta>=0.1",
102
- ]
103
- llamaindex = [
104
- "llama-index-core>=0.11",
105
- ]
106
- nemo-guardrails = [
107
- "nemoguardrails>=0.9",
108
- ]
109
- openai-agents = [
110
- "openai-agents>=0.1",
111
- ]
112
- prefect = [
113
- "prefect>=3.0",
114
- ]
115
- pydanticai = [
116
- "pydantic-ai>=0.1",
117
- ]
118
- smolagents = [
119
- "smolagents>=1.0",
120
- ]
121
- temporal = [
122
- "temporalio>=1.7",
123
- ]
124
- groq = [
125
- "httpx>=0.27",
126
- ]
127
- fireworks = [
128
- "httpx>=0.27",
129
- ]
130
- together = [
131
- "httpx>=0.27",
132
- ]
133
- deepinfra = [
134
- "httpx>=0.27",
135
- ]
136
- ollama = [
137
- "httpx>=0.27",
138
- ]
139
- vllm = [
140
- "httpx>=0.27",
141
- ]
142
- # Convenience: every framework/provider integration at once.
143
- all-integrations = [
144
- "ag2>=0.4",
145
- "agno>=1.0",
146
- "langchain-core>=0.3",
147
- "beeai-framework>=0.1",
148
- "camel-ai>=0.2",
149
- "controlflow>=0.11",
150
- "crewai>=0.80",
151
- "dspy>=2.0",
152
- "google-adk>=0.1",
153
- "instructor>=1.0",
154
- "langchain-core>=0.3",
155
- "langgraph-checkpoint>=2.0",
156
- "letta>=0.1",
157
- "llama-index-core>=0.11",
158
- "nemoguardrails>=0.9",
159
- "openai-agents>=0.1",
160
- "prefect>=3.0",
161
- "pydantic-ai>=0.1",
162
- "smolagents>=1.0",
163
- "temporalio>=1.7",
164
- "httpx>=0.27",
165
- ]
166
-
167
- [project.urls]
168
- Homepage = "https://cortexdb.ai"
169
- Documentation = "https://docs.cortexdb.ai"
170
- Repository = "https://github.com/cortexdb/cortexdb"
171
- Issues = "https://github.com/cortexdb/cortexdb/issues"
172
- Changelog = "https://github.com/cortexdb/cortexdb/blob/main/CHANGELOG.md"
173
-
174
- [tool.hatch.build.targets.wheel]
175
- packages = ["cortexdb"]
176
-
177
- [tool.ruff]
178
- target-version = "py310"
179
- line-length = 100
180
-
181
- [tool.ruff.lint]
182
- select = ["E", "F", "W", "I", "N", "UP", "B", "A", "SIM", "TCH"]
183
-
184
- [tool.pytest.ini_options]
185
- asyncio_mode = "auto"
186
- testpaths = ["tests"]
1
+ [build-system]
2
+ requires = ["hatchling"]
3
+ build-backend = "hatchling.build"
4
+
5
+ [project]
6
+ name = "cortexdbai"
7
+ version = "0.10.0"
8
+ description = "The Long-Term Memory Layer for AI Systems"
9
+ readme = "README.md"
10
+ license = "Apache-2.0"
11
+ # 3.10+: the v1 module uses PEP 604 unions (`str | None`) in TypedDict
12
+ # field annotations, which Python 3.9 cannot evaluate at class-definition
13
+ # time even with `from __future__ import annotations`. Python 3.9 hit
14
+ # end-of-life on 2025-10-31. Declaring >=3.10 means `pip install
15
+ # cortexdbai` on 3.9 fails immediately with a clear "requires Python
16
+ # 3.10+" error from pip — not a silent install followed by an obscure
17
+ # `TypeError: Unable to evaluate type annotation 'str | None'` on the
18
+ # first import.
19
+ requires-python = ">=3.10"
20
+ authors = [
21
+ { name = "Prashant Malik", email = "prashant@cortexdb.ai" },
22
+ ]
23
+ keywords = ["ai", "memory", "llm", "knowledge-graph", "event-sourcing", "cortexdb"]
24
+ classifiers = [
25
+ "Development Status :: 4 - Beta",
26
+ "Intended Audience :: Developers",
27
+ "Programming Language :: Python :: 3",
28
+ "Programming Language :: Python :: 3.10",
29
+ "Programming Language :: Python :: 3.11",
30
+ "Programming Language :: Python :: 3.12",
31
+ "Programming Language :: Python :: 3.13",
32
+ "Topic :: Scientific/Engineering :: Artificial Intelligence",
33
+ "Topic :: Database",
34
+ "Typing :: Typed",
35
+ ]
36
+ dependencies = [
37
+ "requests>=2.31",
38
+ "httpx>=0.24",
39
+ "pydantic>=2.0",
40
+ "tenacity>=8.0",
41
+ ]
42
+
43
+ [project.optional-dependencies]
44
+ async = [
45
+ "httpx[http2]",
46
+ ]
47
+ dev = [
48
+ "pytest>=8.0",
49
+ "pytest-asyncio>=0.23",
50
+ "ruff>=0.4",
51
+ ]
52
+
53
+ # --- Framework / provider integrations -------------------------------------
54
+ # Each extra pulls in only the third-party framework needed by the matching
55
+ # submodule under `cortexdb.integrations.<name>`. The CortexDB client itself
56
+ # is always the base package, so it is never listed here. Nothing under
57
+ # `cortexdb.integrations` is imported at `import cortexdb` time — importing a
58
+ # submodule without its extra raises a clean ModuleNotFoundError.
59
+ autogen = [
60
+ "ag2>=0.4",
61
+ ]
62
+ ag2 = [
63
+ "ag2>=0.4",
64
+ ]
65
+ agno = [
66
+ "agno>=1.0",
67
+ ]
68
+ langchain = [
69
+ "langchain-core>=0.3",
70
+ ]
71
+ beeai = [
72
+ "beeai-framework>=0.1",
73
+ ]
74
+ camel = [
75
+ "camel-ai>=0.2",
76
+ ]
77
+ controlflow = [
78
+ "controlflow>=0.11",
79
+ ]
80
+ crewai = [
81
+ "crewai>=0.80",
82
+ ]
83
+ dify = []
84
+ dspy = [
85
+ "dspy>=2.0",
86
+ ]
87
+ flowise = []
88
+ google-adk = [
89
+ "google-adk>=0.1",
90
+ ]
91
+ hermes = []
92
+ instructor = [
93
+ "instructor>=1.0",
94
+ "pydantic>=2.0",
95
+ ]
96
+ langgraph = [
97
+ "langchain-core>=0.3",
98
+ "langgraph-checkpoint>=2.0",
99
+ ]
100
+ letta = [
101
+ "letta>=0.1",
102
+ ]
103
+ llamaindex = [
104
+ "llama-index-core>=0.11",
105
+ ]
106
+ nemo-guardrails = [
107
+ "nemoguardrails>=0.9",
108
+ ]
109
+ openai-agents = [
110
+ "openai-agents>=0.1",
111
+ ]
112
+ prefect = [
113
+ "prefect>=3.0",
114
+ ]
115
+ pydanticai = [
116
+ "pydantic-ai>=0.1",
117
+ ]
118
+ smolagents = [
119
+ "smolagents>=1.0",
120
+ ]
121
+ temporal = [
122
+ "temporalio>=1.7",
123
+ ]
124
+ groq = [
125
+ "httpx>=0.27",
126
+ ]
127
+ fireworks = [
128
+ "httpx>=0.27",
129
+ ]
130
+ together = [
131
+ "httpx>=0.27",
132
+ ]
133
+ deepinfra = [
134
+ "httpx>=0.27",
135
+ ]
136
+ ollama = [
137
+ "httpx>=0.27",
138
+ ]
139
+ vllm = [
140
+ "httpx>=0.27",
141
+ ]
142
+ # Convenience: every framework/provider integration at once.
143
+ all-integrations = [
144
+ "ag2>=0.4",
145
+ "agno>=1.0",
146
+ "langchain-core>=0.3",
147
+ "beeai-framework>=0.1",
148
+ "camel-ai>=0.2",
149
+ "controlflow>=0.11",
150
+ "crewai>=0.80",
151
+ "dspy>=2.0",
152
+ "google-adk>=0.1",
153
+ "instructor>=1.0",
154
+ "langchain-core>=0.3",
155
+ "langgraph-checkpoint>=2.0",
156
+ "letta>=0.1",
157
+ "llama-index-core>=0.11",
158
+ "nemoguardrails>=0.9",
159
+ "openai-agents>=0.1",
160
+ "prefect>=3.0",
161
+ "pydantic-ai>=0.1",
162
+ "smolagents>=1.0",
163
+ "temporalio>=1.7",
164
+ "httpx>=0.27",
165
+ ]
166
+
167
+ [project.urls]
168
+ Homepage = "https://cortexdb.ai"
169
+ Documentation = "https://docs.cortexdb.ai"
170
+ Repository = "https://github.com/cortexdb/cortexdb"
171
+ Issues = "https://github.com/cortexdb/cortexdb/issues"
172
+ Changelog = "https://github.com/cortexdb/cortexdb/blob/main/CHANGELOG.md"
173
+
174
+ [tool.hatch.build.targets.wheel]
175
+ packages = ["cortexdb"]
176
+
177
+ [tool.ruff]
178
+ target-version = "py310"
179
+ line-length = 100
180
+
181
+ [tool.ruff.lint]
182
+ select = ["E", "F", "W", "I", "N", "UP", "B", "A", "SIM", "TCH"]
183
+
184
+ [tool.pytest.ini_options]
185
+ asyncio_mode = "auto"
186
+ testpaths = ["tests"]
File without changes
File without changes