kognite 0.1.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.
kognite-0.1.0/PKG-INFO ADDED
@@ -0,0 +1,101 @@
1
+ Metadata-Version: 2.4
2
+ Name: kognite
3
+ Version: 0.1.0
4
+ Summary: Python SDK for Kognite — long-term memory for AI agents (hybrid semantic search, memory formation, knowledge graph)
5
+ Author-email: Kognite <hello@kognite.dev>
6
+ License: MIT
7
+ Project-URL: Homepage, https://kognite.dev
8
+ Project-URL: Repository, https://github.com/global-software-development-eu/memcore-portable-agent-memory-saas
9
+ Keywords: kognite,agent-memory,memory,llm,rag,sdk,ai
10
+ Classifier: Development Status :: 4 - Beta
11
+ Classifier: Intended Audience :: Developers
12
+ Classifier: License :: OSI Approved :: MIT License
13
+ Classifier: Programming Language :: Python :: 3
14
+ Classifier: Programming Language :: Python :: 3.9
15
+ Classifier: Programming Language :: Python :: 3.10
16
+ Classifier: Programming Language :: Python :: 3.11
17
+ Classifier: Programming Language :: Python :: 3.12
18
+ Classifier: Programming Language :: Python :: 3.13
19
+ Classifier: Topic :: Software Development :: Libraries :: Python Modules
20
+ Requires-Python: >=3.9
21
+ Description-Content-Type: text/markdown
22
+
23
+ # kognite
24
+
25
+ Python SDK for [Kognite](https://kognite.dev) — long-term memory for AI agents.
26
+ Hybrid semantic + full-text search, LLM memory formation, and a knowledge graph,
27
+ behind one API key. **Zero dependencies** (stdlib only), Python 3.9+.
28
+
29
+ ```bash
30
+ pip install kognite
31
+ ```
32
+
33
+ ## Quickstart
34
+
35
+ ```python
36
+ from kognite import Kognite
37
+
38
+ k = Kognite(api_key="kgn_...")
39
+
40
+ # Store a memory
41
+ k.memories.add("User prefers dark mode", kind="preference")
42
+
43
+ # Hybrid search (semantic + full-text, RRF-fused)
44
+ hits = k.memories.search("ui preferences", limit=5)["results"]
45
+
46
+ # Highest precision (cross-encoder rerank — slower):
47
+ k.memories.search("ui preferences", rerank=True)
48
+ ```
49
+
50
+ ## Memory formation (the good stuff)
51
+
52
+ `ingest` runs the pipeline behind Kognite's published LoCoMo results: it stores
53
+ raw messages as episodes **and** extracts atomic facts — pronouns resolved to
54
+ names, relative dates converted to absolute ones. Prefer it over `add` for any
55
+ multi-message context:
56
+
57
+ ```python
58
+ k.memories.ingest([
59
+ {"speaker": "user", "timestamp": "2026-07-15", "content": "I moved to Berlin last month."},
60
+ {"speaker": "assistant", "content": "Noted — how are you finding it?"},
61
+ ])
62
+ # → {"raw": 2, "extracted": 1, "stored": 3}
63
+ ```
64
+
65
+ ## Context assembly
66
+
67
+ A token-budgeted bundle of relevant memories, ready to drop into a prompt:
68
+
69
+ ```python
70
+ ctx = k.context.assemble("user's living situation", token_budget=2000)
71
+ ```
72
+
73
+ ## Everything else
74
+
75
+ ```python
76
+ k.memories.get(memory_id)
77
+ k.memories.forget(memory_id) # soft-delete (+ graph cascade)
78
+ k.memories.list(limit=50) # newest-first paging
79
+ k.graph.query("Berlin") # knowledge-graph search
80
+ k.health()
81
+ ```
82
+
83
+ Errors raise `KogniteError` with `.status` (HTTP) and `.code`
84
+ (`validation_failed`, `quota_exceeded`, `not_found`, …). Retries with
85
+ exponential backoff on 429/5xx/network errors are built in.
86
+
87
+ The tenant scope is derived server-side from your API key — the SDK has no
88
+ scope parameter and cannot reach another tenant. Get a key in the
89
+ [dashboard](https://app.kognite.dev), and see the live, judge-audited
90
+ [benchmarks](https://kognite.dev/benchmarks).
91
+
92
+ Self-hosted? Pass `base_url=` to the constructor.
93
+
94
+ ## Development
95
+
96
+ `smoke_live.py` is a full live-API exercise of every method (safe: runs in the
97
+ key's own scope and forgets everything it creates):
98
+
99
+ ```bash
100
+ KOGNITE_API_KEY=kgn_... python smoke_live.py
101
+ ```
@@ -0,0 +1,79 @@
1
+ # kognite
2
+
3
+ Python SDK for [Kognite](https://kognite.dev) — long-term memory for AI agents.
4
+ Hybrid semantic + full-text search, LLM memory formation, and a knowledge graph,
5
+ behind one API key. **Zero dependencies** (stdlib only), Python 3.9+.
6
+
7
+ ```bash
8
+ pip install kognite
9
+ ```
10
+
11
+ ## Quickstart
12
+
13
+ ```python
14
+ from kognite import Kognite
15
+
16
+ k = Kognite(api_key="kgn_...")
17
+
18
+ # Store a memory
19
+ k.memories.add("User prefers dark mode", kind="preference")
20
+
21
+ # Hybrid search (semantic + full-text, RRF-fused)
22
+ hits = k.memories.search("ui preferences", limit=5)["results"]
23
+
24
+ # Highest precision (cross-encoder rerank — slower):
25
+ k.memories.search("ui preferences", rerank=True)
26
+ ```
27
+
28
+ ## Memory formation (the good stuff)
29
+
30
+ `ingest` runs the pipeline behind Kognite's published LoCoMo results: it stores
31
+ raw messages as episodes **and** extracts atomic facts — pronouns resolved to
32
+ names, relative dates converted to absolute ones. Prefer it over `add` for any
33
+ multi-message context:
34
+
35
+ ```python
36
+ k.memories.ingest([
37
+ {"speaker": "user", "timestamp": "2026-07-15", "content": "I moved to Berlin last month."},
38
+ {"speaker": "assistant", "content": "Noted — how are you finding it?"},
39
+ ])
40
+ # → {"raw": 2, "extracted": 1, "stored": 3}
41
+ ```
42
+
43
+ ## Context assembly
44
+
45
+ A token-budgeted bundle of relevant memories, ready to drop into a prompt:
46
+
47
+ ```python
48
+ ctx = k.context.assemble("user's living situation", token_budget=2000)
49
+ ```
50
+
51
+ ## Everything else
52
+
53
+ ```python
54
+ k.memories.get(memory_id)
55
+ k.memories.forget(memory_id) # soft-delete (+ graph cascade)
56
+ k.memories.list(limit=50) # newest-first paging
57
+ k.graph.query("Berlin") # knowledge-graph search
58
+ k.health()
59
+ ```
60
+
61
+ Errors raise `KogniteError` with `.status` (HTTP) and `.code`
62
+ (`validation_failed`, `quota_exceeded`, `not_found`, …). Retries with
63
+ exponential backoff on 429/5xx/network errors are built in.
64
+
65
+ The tenant scope is derived server-side from your API key — the SDK has no
66
+ scope parameter and cannot reach another tenant. Get a key in the
67
+ [dashboard](https://app.kognite.dev), and see the live, judge-audited
68
+ [benchmarks](https://kognite.dev/benchmarks).
69
+
70
+ Self-hosted? Pass `base_url=` to the constructor.
71
+
72
+ ## Development
73
+
74
+ `smoke_live.py` is a full live-API exercise of every method (safe: runs in the
75
+ key's own scope and forgets everything it creates):
76
+
77
+ ```bash
78
+ KOGNITE_API_KEY=kgn_... python smoke_live.py
79
+ ```
@@ -0,0 +1,22 @@
1
+ """
2
+ Kognite Python SDK — long-term memory for AI agents.
3
+
4
+ Usage::
5
+
6
+ from kognite import Kognite
7
+
8
+ k = Kognite(api_key="kgn_your_api_key")
9
+
10
+ k.memories.add("User prefers dark mode", kind="preference")
11
+ hits = k.memories.search("ui preferences")["results"]
12
+
13
+ # Memory formation (episodes + extracted atomic facts):
14
+ k.memories.ingest([
15
+ {"speaker": "user", "timestamp": "2026-07-15", "content": "I moved to Berlin last month."},
16
+ ])
17
+ """
18
+
19
+ from kognite.client import Kognite, KogniteError
20
+
21
+ __all__ = ["Kognite", "KogniteError"]
22
+ __version__ = "0.1.0"
@@ -0,0 +1,282 @@
1
+ """
2
+ Kognite Python SDK — typed client for the Kognite memory API.
3
+
4
+ Zero dependencies (stdlib urllib). The scope (tenant) is derived server-side
5
+ from the API key — there is no scope parameter anywhere in this SDK.
6
+
7
+ Usage::
8
+
9
+ from kognite import Kognite
10
+
11
+ k = Kognite(api_key="kgn_...")
12
+ k.memories.add("User prefers dark mode", kind="preference")
13
+ hits = k.memories.search("ui preferences")["results"]
14
+ """
15
+
16
+ from __future__ import annotations
17
+
18
+ import json
19
+ import random
20
+ import time
21
+ import urllib.error
22
+ import urllib.parse
23
+ import urllib.request
24
+ from typing import Any, Dict, List, Optional
25
+
26
+ DEFAULT_BASE_URL = "https://api.kognite.dev"
27
+ _RETRYABLE = lambda status: status == 429 or status >= 500 # noqa: E731
28
+
29
+
30
+ class KogniteError(Exception):
31
+ """Raised on any non-2xx API response.
32
+
33
+ Attributes:
34
+ status: HTTP status code.
35
+ code: API error code (e.g. "validation_failed", "quota_exceeded", "not_found").
36
+ """
37
+
38
+ def __init__(self, status: int, code: str, message: str) -> None:
39
+ self.status = status
40
+ self.code = code
41
+ super().__init__(f"[{status}] {code}: {message}")
42
+
43
+
44
+ class Kognite:
45
+ """Kognite API client.
46
+
47
+ Args:
48
+ api_key: Kognite API key (PAT) from the dashboard.
49
+ base_url: Override for self-hosted deployments (default https://api.kognite.dev).
50
+ max_retries: Retries on 429/5xx/network errors (default 3).
51
+ retry_base_delay: Base seconds for exponential backoff (default 0.5).
52
+ timeout: Per-request timeout in seconds (default 30).
53
+ """
54
+
55
+ def __init__(
56
+ self,
57
+ api_key: str,
58
+ base_url: str = DEFAULT_BASE_URL,
59
+ max_retries: int = 3,
60
+ retry_base_delay: float = 0.5,
61
+ timeout: float = 30.0,
62
+ ) -> None:
63
+ if not api_key:
64
+ raise ValueError("Kognite: api_key is required")
65
+ self._api_key = api_key
66
+ self._base_url = base_url.rstrip("/")
67
+ self._max_retries = max_retries
68
+ self._retry_base_delay = retry_base_delay
69
+ self._timeout = timeout
70
+ self.memories = _Memories(self)
71
+ self.context = _Context(self)
72
+ self.graph = _Graph(self)
73
+
74
+ # ── HTTP core ────────────────────────────────────────────────────────────
75
+
76
+ def _request(
77
+ self,
78
+ method: str,
79
+ path: str,
80
+ body: Optional[Dict[str, Any]] = None,
81
+ query: Optional[Dict[str, Any]] = None,
82
+ ) -> Any:
83
+ url = self._base_url + path
84
+ if query:
85
+ filtered = {k: v for k, v in query.items() if v is not None}
86
+ if filtered:
87
+ url += "?" + urllib.parse.urlencode(filtered)
88
+
89
+ data = json.dumps(body).encode("utf-8") if body is not None else None
90
+ headers = {
91
+ "Authorization": f"Bearer {self._api_key}",
92
+ "Accept": "application/json",
93
+ # A real UA matters: Cloudflare (in front of api.kognite.dev)
94
+ # rejects the default Python-urllib agent with a 403.
95
+ "User-Agent": "kognite-python/0.1.0",
96
+ }
97
+ if data is not None:
98
+ headers["Content-Type"] = "application/json"
99
+
100
+ last_error: Optional[Exception] = None
101
+ for attempt in range(self._max_retries + 1):
102
+ req = urllib.request.Request(url, data=data, headers=headers, method=method)
103
+ try:
104
+ with urllib.request.urlopen(req, timeout=self._timeout) as res:
105
+ if res.status == 204:
106
+ return None
107
+ return json.loads(res.read().decode("utf-8"))
108
+ except urllib.error.HTTPError as e:
109
+ status = e.code
110
+ if _RETRYABLE(status) and attempt < self._max_retries:
111
+ time.sleep(random.random() * self._retry_base_delay * (2**attempt))
112
+ continue
113
+ try:
114
+ parsed = json.loads(e.read().decode("utf-8"))
115
+ err = parsed.get("error") or {}
116
+ except Exception:
117
+ err = {}
118
+ raise KogniteError(
119
+ status, err.get("code", "http_error"), err.get("message", f"HTTP {status}")
120
+ ) from None
121
+ except (urllib.error.URLError, TimeoutError, OSError) as e:
122
+ last_error = e
123
+ if attempt < self._max_retries:
124
+ time.sleep(random.random() * self._retry_base_delay * (2**attempt))
125
+ continue
126
+ raise KogniteError(0, "network_error", str(last_error))
127
+
128
+ # ── Health ───────────────────────────────────────────────────────────────
129
+
130
+ def health(self) -> Dict[str, Any]:
131
+ """Liveness check (no auth required by the API)."""
132
+ return self._request("GET", "/api/health")
133
+
134
+
135
+ class _Memories:
136
+ """Memory store — add, search, list, get, forget, batch ingest."""
137
+
138
+ def __init__(self, client: Kognite) -> None:
139
+ self._c = client
140
+
141
+ def add(
142
+ self,
143
+ content: str,
144
+ kind: Optional[str] = None,
145
+ confidence: Optional[float] = None,
146
+ metadata: Optional[Dict[str, Any]] = None,
147
+ source: Optional[str] = None,
148
+ idempotency_key: Optional[str] = None,
149
+ ) -> Dict[str, Any]:
150
+ """Store a single memory. Returns ``{"id": ..., "created_at": ...}``."""
151
+ body: Dict[str, Any] = {"content": content}
152
+ if kind is not None:
153
+ body["kind"] = kind
154
+ if confidence is not None:
155
+ body["confidence"] = confidence
156
+ if metadata is not None:
157
+ body["metadata"] = metadata
158
+ if source is not None:
159
+ body["source"] = source
160
+ if idempotency_key is not None:
161
+ body["idempotency_key"] = idempotency_key
162
+ return self._c._request("POST", "/api/memories", body)["data"]
163
+
164
+ def search(
165
+ self,
166
+ query: str,
167
+ limit: Optional[int] = None,
168
+ offset: Optional[int] = None,
169
+ kind: Optional[str] = None,
170
+ min_confidence: Optional[float] = None,
171
+ rerank: bool = False,
172
+ rerank_n: Optional[int] = None,
173
+ ) -> Dict[str, Any]:
174
+ """Hybrid semantic + full-text search.
175
+
176
+ Returns ``{"results": [...], "total": int, "capped": bool}``. Pass
177
+ ``rerank=True`` for the highest-precision (slower) cross-encoder path.
178
+ """
179
+ return self._c._request(
180
+ "GET",
181
+ "/api/memories",
182
+ query={
183
+ "q": query,
184
+ "limit": limit,
185
+ "offset": offset,
186
+ "kind": kind,
187
+ "min_confidence": min_confidence,
188
+ "rerank": 1 if rerank else None,
189
+ "rerank_n": rerank_n if rerank else None,
190
+ },
191
+ )
192
+
193
+ def list(
194
+ self,
195
+ limit: Optional[int] = None,
196
+ offset: Optional[int] = None,
197
+ kind: Optional[str] = None,
198
+ min_confidence: Optional[float] = None,
199
+ ) -> Dict[str, Any]:
200
+ """Page through memories newest-first. Returns ``{"data": [...], "meta": {...}}``."""
201
+ return self._c._request(
202
+ "GET",
203
+ "/api/memories",
204
+ query={
205
+ "limit": limit,
206
+ "offset": offset,
207
+ "kind": kind,
208
+ "min_confidence": min_confidence,
209
+ },
210
+ )
211
+
212
+ def get(self, memory_id: str) -> Dict[str, Any]:
213
+ """Fetch one memory by id."""
214
+ return self._c._request("GET", f"/api/memories/{urllib.parse.quote(memory_id)}")["data"]
215
+
216
+ def forget(self, memory_id: str) -> None:
217
+ """Soft-delete a memory (and any graph nodes it alone supported)."""
218
+ self._c._request("DELETE", f"/api/memories/{urllib.parse.quote(memory_id)}")
219
+
220
+ def ingest(
221
+ self,
222
+ messages: List[Dict[str, Any]],
223
+ extract: bool = True,
224
+ store_raw: bool = True,
225
+ ) -> Dict[str, Any]:
226
+ """Batch conversational ingest — the memory-formation pipeline.
227
+
228
+ Stores raw messages as episodes AND extracts atomic facts (names
229
+ resolved, relative dates made absolute). This is what powers Kognite's
230
+ published LoCoMo results; prefer it over ``add`` for any multi-message
231
+ context. Each message: ``{"content": str, "id"?: str, "speaker"?: str,
232
+ "timestamp"?: str}``. Returns ``{"raw": n, "extracted": n, "stored": n}``.
233
+ """
234
+ return self._c._request(
235
+ "POST",
236
+ "/api/memories/ingest",
237
+ {"messages": messages, "extract": extract, "store_raw": store_raw},
238
+ )
239
+
240
+
241
+ class _Context:
242
+ """Context assembly — a token-budgeted bundle of relevant memories."""
243
+
244
+ def __init__(self, client: Kognite) -> None:
245
+ self._c = client
246
+
247
+ def assemble(
248
+ self,
249
+ query: str,
250
+ token_budget: Optional[int] = None,
251
+ max_results: Optional[int] = None,
252
+ kinds: Optional[List[str]] = None,
253
+ min_confidence: Optional[float] = None,
254
+ include_skills: bool = False,
255
+ include_graph: bool = True,
256
+ ) -> Dict[str, Any]:
257
+ """Assemble a context bundle for a query, packed under a token budget."""
258
+ body: Dict[str, Any] = {
259
+ "query": query,
260
+ "include_skills": include_skills,
261
+ "include_graph": include_graph,
262
+ }
263
+ if token_budget is not None:
264
+ body["token_budget"] = token_budget
265
+ if max_results is not None:
266
+ body["max_results"] = max_results
267
+ if kinds is not None:
268
+ body["kinds"] = kinds
269
+ if min_confidence is not None:
270
+ body["min_confidence"] = min_confidence
271
+ return self._c._request("POST", "/api/context/assemble", body)["data"]
272
+
273
+
274
+ class _Graph:
275
+ """Knowledge-graph overview / entity search."""
276
+
277
+ def __init__(self, client: Kognite) -> None:
278
+ self._c = client
279
+
280
+ def query(self, q: Optional[str] = None) -> Dict[str, Any]:
281
+ """Graph overview; pass ``q`` to also search entities/relationships."""
282
+ return self._c._request("GET", "/api/knowledge-graph", query={"q": q} if q else None)["data"]
@@ -0,0 +1,101 @@
1
+ Metadata-Version: 2.4
2
+ Name: kognite
3
+ Version: 0.1.0
4
+ Summary: Python SDK for Kognite — long-term memory for AI agents (hybrid semantic search, memory formation, knowledge graph)
5
+ Author-email: Kognite <hello@kognite.dev>
6
+ License: MIT
7
+ Project-URL: Homepage, https://kognite.dev
8
+ Project-URL: Repository, https://github.com/global-software-development-eu/memcore-portable-agent-memory-saas
9
+ Keywords: kognite,agent-memory,memory,llm,rag,sdk,ai
10
+ Classifier: Development Status :: 4 - Beta
11
+ Classifier: Intended Audience :: Developers
12
+ Classifier: License :: OSI Approved :: MIT License
13
+ Classifier: Programming Language :: Python :: 3
14
+ Classifier: Programming Language :: Python :: 3.9
15
+ Classifier: Programming Language :: Python :: 3.10
16
+ Classifier: Programming Language :: Python :: 3.11
17
+ Classifier: Programming Language :: Python :: 3.12
18
+ Classifier: Programming Language :: Python :: 3.13
19
+ Classifier: Topic :: Software Development :: Libraries :: Python Modules
20
+ Requires-Python: >=3.9
21
+ Description-Content-Type: text/markdown
22
+
23
+ # kognite
24
+
25
+ Python SDK for [Kognite](https://kognite.dev) — long-term memory for AI agents.
26
+ Hybrid semantic + full-text search, LLM memory formation, and a knowledge graph,
27
+ behind one API key. **Zero dependencies** (stdlib only), Python 3.9+.
28
+
29
+ ```bash
30
+ pip install kognite
31
+ ```
32
+
33
+ ## Quickstart
34
+
35
+ ```python
36
+ from kognite import Kognite
37
+
38
+ k = Kognite(api_key="kgn_...")
39
+
40
+ # Store a memory
41
+ k.memories.add("User prefers dark mode", kind="preference")
42
+
43
+ # Hybrid search (semantic + full-text, RRF-fused)
44
+ hits = k.memories.search("ui preferences", limit=5)["results"]
45
+
46
+ # Highest precision (cross-encoder rerank — slower):
47
+ k.memories.search("ui preferences", rerank=True)
48
+ ```
49
+
50
+ ## Memory formation (the good stuff)
51
+
52
+ `ingest` runs the pipeline behind Kognite's published LoCoMo results: it stores
53
+ raw messages as episodes **and** extracts atomic facts — pronouns resolved to
54
+ names, relative dates converted to absolute ones. Prefer it over `add` for any
55
+ multi-message context:
56
+
57
+ ```python
58
+ k.memories.ingest([
59
+ {"speaker": "user", "timestamp": "2026-07-15", "content": "I moved to Berlin last month."},
60
+ {"speaker": "assistant", "content": "Noted — how are you finding it?"},
61
+ ])
62
+ # → {"raw": 2, "extracted": 1, "stored": 3}
63
+ ```
64
+
65
+ ## Context assembly
66
+
67
+ A token-budgeted bundle of relevant memories, ready to drop into a prompt:
68
+
69
+ ```python
70
+ ctx = k.context.assemble("user's living situation", token_budget=2000)
71
+ ```
72
+
73
+ ## Everything else
74
+
75
+ ```python
76
+ k.memories.get(memory_id)
77
+ k.memories.forget(memory_id) # soft-delete (+ graph cascade)
78
+ k.memories.list(limit=50) # newest-first paging
79
+ k.graph.query("Berlin") # knowledge-graph search
80
+ k.health()
81
+ ```
82
+
83
+ Errors raise `KogniteError` with `.status` (HTTP) and `.code`
84
+ (`validation_failed`, `quota_exceeded`, `not_found`, …). Retries with
85
+ exponential backoff on 429/5xx/network errors are built in.
86
+
87
+ The tenant scope is derived server-side from your API key — the SDK has no
88
+ scope parameter and cannot reach another tenant. Get a key in the
89
+ [dashboard](https://app.kognite.dev), and see the live, judge-audited
90
+ [benchmarks](https://kognite.dev/benchmarks).
91
+
92
+ Self-hosted? Pass `base_url=` to the constructor.
93
+
94
+ ## Development
95
+
96
+ `smoke_live.py` is a full live-API exercise of every method (safe: runs in the
97
+ key's own scope and forgets everything it creates):
98
+
99
+ ```bash
100
+ KOGNITE_API_KEY=kgn_... python smoke_live.py
101
+ ```
@@ -0,0 +1,8 @@
1
+ README.md
2
+ pyproject.toml
3
+ kognite/__init__.py
4
+ kognite/client.py
5
+ kognite.egg-info/PKG-INFO
6
+ kognite.egg-info/SOURCES.txt
7
+ kognite.egg-info/dependency_links.txt
8
+ kognite.egg-info/top_level.txt
@@ -0,0 +1 @@
1
+ kognite
@@ -0,0 +1,36 @@
1
+ [build-system]
2
+ requires = ["setuptools>=68.0", "wheel"]
3
+ build-backend = "setuptools.build_meta"
4
+
5
+ [project]
6
+ name = "kognite"
7
+ version = "0.1.0"
8
+ description = "Python SDK for Kognite — long-term memory for AI agents (hybrid semantic search, memory formation, knowledge graph)"
9
+ readme = "README.md"
10
+ license = {text = "MIT"}
11
+ authors = [
12
+ {name = "Kognite", email = "hello@kognite.dev"},
13
+ ]
14
+ keywords = ["kognite", "agent-memory", "memory", "llm", "rag", "sdk", "ai"]
15
+ classifiers = [
16
+ "Development Status :: 4 - Beta",
17
+ "Intended Audience :: Developers",
18
+ "License :: OSI Approved :: MIT License",
19
+ "Programming Language :: Python :: 3",
20
+ "Programming Language :: Python :: 3.9",
21
+ "Programming Language :: Python :: 3.10",
22
+ "Programming Language :: Python :: 3.11",
23
+ "Programming Language :: Python :: 3.12",
24
+ "Programming Language :: Python :: 3.13",
25
+ "Topic :: Software Development :: Libraries :: Python Modules",
26
+ ]
27
+ requires-python = ">=3.9"
28
+ # Zero runtime dependencies — stdlib urllib only.
29
+ dependencies = []
30
+
31
+ [project.urls]
32
+ Homepage = "https://kognite.dev"
33
+ Repository = "https://github.com/global-software-development-eu/memcore-portable-agent-memory-saas"
34
+
35
+ [tool.setuptools.packages.find]
36
+ include = ["kognite*"]
@@ -0,0 +1,4 @@
1
+ [egg_info]
2
+ tag_build =
3
+ tag_date = 0
4
+