Skip to content

Commit a534ce4

Browse files
committed
chore: merge main into feat/native-agent-harness, resolve conflicts
Content conflicts resolved: - README.md: keep branch's extended examples list - vektori/client.py: keep skip_extraction param, adopt result= style from main - vektori/retrieval/scoring.py: use already-parsed meta dict (main's approach) - tests/unit/test_factory.py: combine both import sets and test suites Restored files dropped by auto-merge: - vektori/context.py (AgentContextLoader used by agent harness) - ChatModelProvider + ChatCompletionResult in vektori/models/base.py - LiteLLMChatModel in vektori/models/litellm_provider.py - OpenAIChatModel in vektori/models/openai.py - CHAT_REGISTRY + create_chat_model in vektori/models/factory.py
2 parents ae0ece4 + bceb4fe commit a534ce4

85 files changed

Lines changed: 25872 additions & 1084 deletions

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

.github/workflows/ci.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,7 @@ jobs:
2222

2323
- name: Install dependencies
2424
run: |
25-
pip install -e ".[dev]"
25+
pip install -e ".[dev,all]"
2626
python -m nltk.downloader punkt_tab
2727
2828
- name: Lint with ruff

.gitignore

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -43,7 +43,7 @@ env/
4343
.coverage
4444
htmlcov/
4545
.tox/
46-
46+
/data
4747
# Environment variables
4848
.env
4949
.env.local
@@ -80,6 +80,18 @@ ISSUES.md
8080
# Demo script (local use only)
8181
examples/demo.py
8282

83+
# Temp/debug data dirs
84+
.codex_pytest_tmp_run/
85+
.codex_pytest_tmp_run2/
86+
.codex_pytest_tmp_run3/
87+
.tmp-vektori-debug-data/
88+
.tmp-vektori-plugin-data/
89+
90+
# Local generated files
91+
demo.html
92+
issues_with_latest_benchmark.md
93+
scripts/dashboard_data.json
94+
8395
# Generated logo PNGs (regenerate with scripts/generate_logo_assets.py)
8496
assets/logo/favicon/
8597
assets/logo/app-icons/

README.md

Lines changed: 105 additions & 53 deletions
Original file line numberDiff line numberDiff line change
@@ -1,21 +1,39 @@
1-
<p align="center">
2-
<img src="assets/logo/memory-stack-logo-transparent.svg" width="96" height="96" alt="Vektori logo" />
3-
</p>
1+
<div align="center">
42

5-
<h1 align="center">Vektori</h1>
3+
<img src="assets/logo/memory-stack-logo-transparent.svg" width="96" height="96" alt="Vektori logo" />
64

7-
<p align="center"><strong>Memory that remembers the story, not just the facts.</strong></p>
5+
<h1>Vektori</h1>
86

9-
<p align="center">
10-
<a href="LICENSE"><img src="https://img.shields.io/badge/License-Apache%202.0-blue.svg" alt="License: Apache 2.0" /></a>
11-
<a href="https://pypi.org/project/vektori/"><img src="https://img.shields.io/pypi/v/vektori" alt="PyPI" /></a>
12-
<a href="https://pypi.org/project/vektori/"><img src="https://img.shields.io/pypi/dm/vektori?color=blue" alt="PyPI Downloads" /></a>
13-
<a href="https://www.python.org/downloads/"><img src="https://img.shields.io/badge/python-3.10+-blue.svg" alt="Python 3.10+" /></a>
14-
</p>
7+
<p><strong>Memory that remembers the story, not just the facts.</strong></p>
8+
9+
<a href="https://github.com/vektori-ai/vektori">GitHub</a> · <a href="https://github.com/vektori-ai/vektori/issues">Issues</a> · <a href="./docs">Docs</a>
10+
11+
[![License](https://img.shields.io/badge/License-Apache%202.0-blue.svg)](LICENSE)
12+
[![PyPI](https://img.shields.io/pypi/v/vektori)](https://pypi.org/project/vektori/)
13+
[![Downloads](https://img.shields.io/pypi/dm/vektori?color=blue)](https://pypi.org/project/vektori/)
14+
[![Python](https://img.shields.io/badge/python-3.10+-blue.svg)](https://www.python.org/downloads/)
15+
[![Stars](https://img.shields.io/github/stars/vektori-ai/vektori?style=flat&color=ffcb47&labelColor=black)](https://github.com/vektori-ai/vektori)
16+
[![Issues](https://img.shields.io/github/issues/vektori-ai/vektori?labelColor=black&style=flat&color=ff80eb)](https://github.com/vektori-ai/vektori/issues)
17+
[![Contributors](https://img.shields.io/github/contributors/vektori-ai/vektori?color=c4f042&labelColor=black&style=flat)](https://github.com/vektori-ai/vektori/graphs/contributors)
18+
[![Last Commit](https://img.shields.io/github/last-commit/vektori-ai/vektori?color=c4f042&labelColor=black)](https://github.com/vektori-ai/vektori/commits/main)
19+
20+
👋 Questions, ideas, bugs → [GitHub Issues](https://github.com/vektori-ai/vektori/issues) · [Discussions](https://github.com/vektori-ai/vektori/discussions)
21+
22+
If Vektori has been useful, a ⭐ goes a long way.
23+
24+
</div>
1525

1626
---
1727

18-
Most memory systems compress conversations into entity-relationship triples. You get the answer, but you lose the texture, the reasoning, the trajectory. Vektori uses a **three-layer sentence graph** so agents don't just recall preferences, they understand how things got there.
28+
## Why Vektori
29+
30+
Building agents that actually remember people is harder than it looks:
31+
32+
- **Facts aren't enough.** Knowing a user prefers WhatsApp is different from knowing they've asked three times and are getting frustrated. Most systems give you the what, not the why or how it changed.
33+
- **Patterns stay invisible.** Spotting that someone's tone has been shifting across sessions requires more than point-in-time retrieval — you need to see the trajectory.
34+
- **Context overhead explodes.** Stuffing raw conversation history into every prompt doesn't scale. You need structure, not just storage.
35+
36+
Vektori solves this with a **three-layer sentence graph**. Agents don't just recall preferences — they understand how things got there.
1937

2038
```
2139
FACT LAYER (L0) <- vector search surface. Short, crisp statements.
@@ -35,11 +53,20 @@ Search hits Facts, graph discovers Episodes, traces back to source Sentences. SQ
3553

3654
## Benchmarks
3755

38-
| Benchmark | Score | Depth | Models |
39-
|-----------|-------|-------|--------|
40-
| LongMemEval-S | **73%** | L1 | BGE-M3 + Gemini Flash |
56+
Tested on long-horizon memory benchmarks — hundreds of turns, real user details buried deep in history.
57+
58+
| Benchmark | Vektori | Mem0 | Zep | Supermemory | Letta |
59+
|-----------|---------|------|-----|-------------|-------|
60+
| LoCoMo | **66%** | 66% | 58%† | ~70% | ~83% |
61+
| LongMemEval-S | **73%** || 64% | 85% ||
62+
63+
†Zep's self-reported score is 75%; independently re-evaluated at 58%. Scores across systems are not always directly comparable — model choice (GPT-4o vs GPT-4.1-mini vs local) significantly affects results.
64+
65+
We used gemini-2.5-flash-lite because of token cost, better models imporve accuracy a lot. Benchmarks at L1 level
4166

42-
Still improving. Run your own in [`/benchmarks`](benchmarks/).
67+
On LoCoMo and longmemEval, **the retrieved context contains the answer in 95% of questions** — the gap to 66% is a synthesis problem, not a retrieval one. Actively working on closing it, exploring RL.
68+
69+
Still improving — PRs and evals welcome. Run your own: [`/benchmarks`](benchmarks/)
4370

4471
---
4572

@@ -111,8 +138,8 @@ Pick how deep you want to go.
111138
| Depth | Returns | ~Tokens | When to use |
112139
|-------|---------|---------|-------------|
113140
| `l0` | Facts only | 50-200 | Fast lookup, agent planning, tool calls |
114-
| `l1` | Facts + Episodes | 200-500 | **Default.** Full answer with context |
115-
| `l2` | Facts + Episodes + raw Sentences | 1000-3000 | Trajectory analysis, full story replay |
141+
| `l1` | Facts + Episodes + source Sentences | 300-800 | **Default.** Full answer with context |
142+
| `l2` | Facts + Episodes + Sentences + ±N context window | 1000-3000 | Trajectory analysis, full story replay |
116143

117144
```python
118145
# Just the facts
@@ -129,45 +156,60 @@ results = await v.search(query, user_id, depth="l2", context_window=3)
129156

130157
## Build an Agent with Memory
131158

132-
The low-level way is still available, but the new native harness is the right default.
159+
Three lines to wire memory into any agent loop:
133160

134161
```python
135162
import asyncio
136-
from vektori import AgentConfig, Vektori, VektoriAgent
137-
from vektori.models.factory import create_chat_model
163+
from openai import AsyncOpenAI
164+
from vektori import Vektori
165+
166+
client = AsyncOpenAI()
138167

139168
async def chat(user_id: str):
140-
memory = Vektori(
169+
v = Vektori(
141170
embedding_model="openai:text-embedding-3-small",
142171
extraction_model="openai:gpt-4o-mini",
143172
)
144-
agent = VektoriAgent(
145-
memory=memory,
146-
model=create_chat_model("openai:gpt-4o-mini"),
147-
user_id=user_id,
148-
agent_id="demo-agent",
149-
session_id=f"session-{user_id}-001",
150-
config=AgentConfig(background_add=True),
151-
)
173+
session_id = f"session-{user_id}-001"
174+
history = []
152175

153176
print("Chat with memory (type 'quit' to exit)\n")
154177
while True:
155178
user_input = input("You: ").strip()
156179
if user_input.lower() == "quit":
157180
break
158-
result = await agent.chat(user_input)
159-
print(f"Assistant: {result.content}\n")
160181

161-
await agent.close()
162-
await memory.close()
182+
# 1. Pull relevant memory
183+
mem = await v.search(query=user_input, user_id=user_id, depth="l1")
184+
facts = "\n".join(f"- {f['text']}" for f in mem.get("facts", []))
185+
episodes = "\n".join(f"- {ep['text']}" for ep in mem.get("episodes", []))
186+
187+
# 2. Inject into system prompt
188+
system = "You are a helpful assistant with memory.\n"
189+
if facts: system += f"\nKnown facts:\n{facts}"
190+
if episodes: system += f"\nBehavioral episodes:\n{episodes}"
191+
192+
# 3. Get response
193+
history.append({"role": "user", "content": user_input})
194+
resp = await client.chat.completions.create(
195+
model="gpt-4o-mini",
196+
messages=[{"role": "system", "content": system}, *history],
197+
)
198+
reply = resp.choices[0].message.content
199+
history.append({"role": "assistant", "content": reply})
200+
print(f"Assistant: {reply}\n")
201+
202+
# 4. Store exchange
203+
await v.add(
204+
messages=[{"role": "user", "content": user_input},
205+
{"role": "assistant", "content": reply}],
206+
session_id=session_id,
207+
user_id=user_id,
208+
)
163209

164-
asyncio.run(chat("demo-user"))
165-
```
166-
167-
You can also run the harness from the CLI:
210+
await v.close()
168211

169-
```bash
170-
vektori agent chat --user-id demo-user --agent-id support-agent
212+
asyncio.run(chat("demo-user"))
171213
```
172214

173215
More examples in [`/examples`](examples/):
@@ -315,26 +357,30 @@ v = Vektori(embedding_model="bge:BAAI/bge-m3")
315357
v = Vektori(extraction_model="litellm:groq/llama3-8b-8192")
316358
```
317359

318-
---
319-
320-
## Why Not Mem0 / Zep?
360+
## NVIDIA NIM - GPU-optimized models via [NVIDIA NIM](https://build.nvidia.com).
361+
```python
362+
# NVIDIA embedding models (Matryoshka: 384-2048 dimensions)
363+
v = Vektori(
364+
embedding_model="nvidia:llama-nemotron-embed-1b-v2",
365+
embedding_dimension=1024, # Optional: 384, 512, 768, 1024, or 2048
366+
)
321367

322-
| | Mem0 / Zep | **Vektori** |
323-
|---|---|---|
324-
| Memory model | Entity-relation triples | Three-layer sentence graph |
325-
| What you get | The answer | The answer + reasoning + story |
326-
| Patterns beyond facts | Manual graph queries | Auto-discovered (Episode layer) |
327-
| Default backend | Requires external DB | SQLite, zero config |
328-
| Fully local / offline | No | Yes (Ollama, BGE-M3, SentenceTransformers) |
329-
| License | Partial OSS | Apache 2.0 |
368+
# NVIDIA LLM models (nvidia/ prefix auto-added)
369+
v = Vektori(extraction_model="nvidia:llama-3.3-nemotron-super-49b-v1")
330370

331-
Mem0 and Zep are solid tools. But they compress conversations into triples, so you get the *what* but not the *why* or how it changed over time. That matters when you're building agents that need to reason about a person's trajectory, not just their current state.
371+
# Third-party models hosted on NVIDIA NIM (use full path)
372+
v = Vektori(extraction_model="nvidia:z-ai/glm5")
332373

374+
```
333375
---
334376

335377
## Contributing
336378

337-
Issues, PRs, and ideas welcome. See [CONTRIBUTING.md](CONTRIBUTING.md).
379+
Vektori is early and there's a lot of ground to cover. If you're building agents that need memory, your real-world feedback is the most valuable thing you can contribute.
380+
381+
- Found a bug or an edge case? [Open an issue](https://github.com/vektori-ai/vektori/issues)
382+
- Have an idea or want to discuss direction? [Start a discussion](https://github.com/vektori-ai/vektori/discussions)
383+
- Want to contribute code? See [CONTRIBUTING.md](CONTRIBUTING.md)
338384

339385
```bash
340386
git clone https://github.com/vektori-ai/vektori
@@ -345,6 +391,12 @@ pytest tests/unit/
345391

346392
---
347393

394+
## Star History
395+
396+
[![Star History Chart](https://api.star-history.com/svg?repos=vektori-ai/vektori&type=timeline)](https://www.star-history.com/#vektori-ai/vektori&type=timeline)
397+
398+
---
399+
348400
## License
349401

350402
Apache 2.0. See [LICENSE](LICENSE).

0 commit comments

Comments
 (0)