Skip to content

Commit 177e1ad

Browse files
authored
Merge pull request #5 from Ashish-dwi99/release/v0.4.0
Release/v0.4.0
2 parents c3eb5ae + 84df0df commit 177e1ad

6 files changed

Lines changed: 217 additions & 13 deletions

File tree

README.md

Lines changed: 115 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@
1616
</p>
1717

1818
<p align="center">
19-
<a href="https://pypi.org/project/engram"><img src="https://img.shields.io/badge/python-3.9%2B-blue.svg" alt="Python 3.9+"></a>
19+
<a href="https://pypi.org/project/engram-memory"><img src="https://img.shields.io/badge/python-3.9%2B-blue.svg" alt="Python 3.9+"></a>
2020
<a href="https://github.com/Ashish-dwi99/Engram/blob/main/LICENSE"><img src="https://img.shields.io/badge/license-MIT-blue.svg" alt="MIT License"></a>
2121
<a href="https://github.com/Ashish-dwi99/Engram/actions"><img src="https://github.com/Ashish-dwi99/Engram/actions/workflows/test.yml/badge.svg" alt="Tests"></a>
2222
<a href="https://github.com/Ashish-dwi99/Engram"><img src="https://img.shields.io/github/stars/Ashish-dwi99/Engram?style=social" alt="GitHub Stars"></a>
@@ -28,15 +28,12 @@
2828
<a href="#%EF%B8%8F-architecture">Architecture</a> &middot;
2929
<a href="#-integrations">Integrations</a> &middot;
3030
<a href="#-api--sdk">API & SDK</a> &middot;
31+
<a href="#-longmemeval-on-colab-gpu">LongMemEval</a> &middot;
3132
<a href="https://github.com/Ashish-dwi99/Engram/blob/main/CHANGELOG.md">Changelog</a>
3233
</p>
3334

3435
---
3536

36-
> **100% free, forever.** No Pro tier, no usage limits, no license keys. Bring your own API key (Gemini, OpenAI, or Ollama). Everything runs locally by default.
37-
38-
---
39-
4037
## Why Engram
4138

4239
Every AI agent you use starts with amnesia. Your coding assistant forgets your preferences between sessions. Your planning agent has no idea what your research agent discovered yesterday. You end up re-explaining context that should already be known.
@@ -64,13 +61,60 @@ But unlike "store everything forever" approaches, Engram treats agents as **untr
6461
## Quick Start
6562

6663
```bash
67-
pip install -e ".[all]" # 1. Install
68-
export GEMINI_API_KEY="your-key" # 2. Set one API key (or OPENAI_API_KEY, or OLLAMA_HOST)
64+
pip install engram-memory # 1. Install from PyPI
65+
export GEMINI_API_KEY="your-key" # 2. Set one key before starting Engram
6966
engram install # 3. Auto-configure Claude Code, Cursor, Codex
7067
```
7168

7269
Restart your agent. Done — it now has persistent memory across sessions.
7370

71+
### PyPI Install Options
72+
73+
```bash
74+
# Default runtime (Gemini + local Qdrant + MemoryClient deps)
75+
pip install engram-memory
76+
77+
# Full stack extras (MCP server + REST API + async + all providers)
78+
pip install "engram-memory[all]"
79+
80+
# OpenAI provider add-on
81+
pip install "engram-memory[openai]"
82+
83+
# Ollama provider add-on
84+
pip install "engram-memory[ollama]"
85+
```
86+
87+
### API Key: When and How to Provide It
88+
89+
Engram reads provider credentials when a process initializes `Memory()` (for example: `engram`, `engram-api`, `engram-mcp`, or your Python app).
90+
91+
1. Set env vars **before** starting those processes.
92+
2. If you change keys, restart the process.
93+
3. Default provider is Gemini, so set `GEMINI_API_KEY` or `GOOGLE_API_KEY` unless you override provider config.
94+
95+
```bash
96+
# Default (Gemini)
97+
export GEMINI_API_KEY="your-key"
98+
engram-api
99+
```
100+
101+
```bash
102+
# OpenAI provider
103+
export OPENAI_API_KEY="your-key"
104+
engram-api
105+
```
106+
107+
```bash
108+
# Ollama (local; no cloud key)
109+
export OLLAMA_HOST="http://localhost:11434"
110+
engram-api
111+
```
112+
113+
For remote usage via `MemoryClient`, provider API keys are needed on the **server** running Engram.
114+
The client only needs:
115+
- `ENGRAM_ADMIN_KEY` (or `admin_key=...`) when minting sessions via `/v1/sessions`
116+
- Bearer session token for normal read/write API calls
117+
74118
**Or with Docker:**
75119

76120
```bash
@@ -569,6 +613,70 @@ Biological inspirations: Ebbinghaus Forgetting Curve → exponential decay, Spac
569613

570614
---
571615

616+
## LongMemEval on Colab (GPU)
617+
618+
Use this flow to benchmark Engram on LongMemEval in Google Colab with GPU acceleration.
619+
620+
```bash
621+
# 1) In Colab: Runtime -> Change runtime type -> GPU
622+
623+
# 2) Install Engram + GPU reader dependencies
624+
pip install -U engram-memory transformers accelerate
625+
626+
# 3) Download LongMemEval data
627+
mkdir -p /content/longmemeval
628+
cd /content/longmemeval
629+
curl -L -o longmemeval_s_cleaned.json \
630+
https://huggingface.co/datasets/xiaowu0162/longmemeval-cleaned/resolve/main/longmemeval_s_cleaned.json
631+
632+
# 4) Run Engram benchmark (HF reader on GPU)
633+
python -m engram.benchmarks.longmemeval \
634+
--dataset-path /content/longmemeval/longmemeval_s_cleaned.json \
635+
--output-jsonl /content/longmemeval/engram_hypotheses.jsonl \
636+
--retrieval-jsonl /content/longmemeval/engram_retrieval.jsonl \
637+
--answer-backend hf \
638+
--hf-model Qwen/Qwen2.5-1.5B-Instruct \
639+
--embedder-provider simple \
640+
--llm-provider mock \
641+
--vector-store-provider memory \
642+
--history-db-path /content/engram-longmemeval.db \
643+
--top-k 8 \
644+
--max-questions 100 \
645+
--skip-abstention
646+
```
647+
648+
Notes:
649+
- The output file is evaluator-compatible (`question_id`, `hypothesis` per line).
650+
- `--include-debug-fields` adds retrieval diagnostics into each output row.
651+
- The command above uses `simple` embedder + `mock` LLM for memory operations, so **no Gemini/OpenAI key is required**.
652+
653+
If you want to run with Gemini only (no extra reader packages), use base install and set key **before** starting the run:
654+
655+
```bash
656+
pip install -U engram-memory
657+
export GEMINI_API_KEY="your-key"
658+
659+
python -m engram.benchmarks.longmemeval \
660+
--dataset-path /content/longmemeval/longmemeval_s_cleaned.json \
661+
--output-jsonl /content/longmemeval/engram_hypotheses.jsonl \
662+
--answer-backend engram-llm \
663+
--llm-provider gemini \
664+
--embedder-provider gemini \
665+
--vector-store-provider memory
666+
```
667+
668+
Optional official QA scoring from the LongMemEval repo:
669+
670+
```bash
671+
cd /content
672+
git clone https://github.com/xiaowu0162/LongMemEval.git
673+
cd /content/LongMemEval/src/evaluation
674+
export OPENAI_API_KEY="your-key"
675+
python evaluate_qa.py gpt-4o /content/longmemeval/engram_hypotheses.jsonl /content/longmemeval/longmemeval_s_cleaned.json
676+
```
677+
678+
---
679+
572680
## Docker
573681

574682
```bash

engram/__init__.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@
2121
from engram.core.echo import EchoProcessor, EchoDepth, EchoResult
2222
from engram.configs.base import MemoryConfig, FadeMemConfig, EchoMemConfig, CategoryMemConfig, ScopeConfig
2323

24-
__version__ = "0.4.0" # Product release: Docker, CI, CLI improvements
24+
__version__ = "0.4.1"
2525
__all__ = [
2626
# Simplified interface (recommended)
2727
"Engram",

engram/embeddings/nvidia.py

Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
1+
import os
2+
from typing import List, Optional
3+
4+
from engram.embeddings.base import BaseEmbedder
5+
6+
7+
class NvidiaEmbedder(BaseEmbedder):
8+
"""Embedding provider for NVIDIA API (OpenAI-compatible). Default model: nv-embedqa-e5-v5."""
9+
10+
def __init__(self, config: Optional[dict] = None):
11+
super().__init__(config)
12+
try:
13+
from openai import OpenAI
14+
except Exception as exc:
15+
raise ImportError("openai package is required for NvidiaEmbedder") from exc
16+
17+
api_key = self.config.get("api_key") or "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"
18+
if not api_key:
19+
raise ValueError(
20+
"NVIDIA API key required. Set config['api_key'] or NVIDIA_API_KEY env var."
21+
)
22+
23+
base_url = self.config.get("base_url", "https://integrate.api.nvidia.com/v1")
24+
self.client = OpenAI(base_url=base_url, api_key=api_key)
25+
self.model = self.config.get("model", "nvidia/nv-embedqa-e5-v5")
26+
27+
def embed(self, text: str, memory_action: Optional[str] = None) -> List[float]:
28+
# NVIDIA embedding models distinguish between passage and query input types
29+
if memory_action in ("search", "forget"):
30+
input_type = "query"
31+
else:
32+
input_type = "passage"
33+
34+
response = self.client.embeddings.create(
35+
input=[text],
36+
model=self.model,
37+
encoding_format="float",
38+
extra_body={"input_type": input_type, "truncate": "NONE"},
39+
)
40+
return response.data[0].embedding

engram/llms/nvidia.py

Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,47 @@
1+
import os
2+
from typing import Optional
3+
4+
from engram.llms.base import BaseLLM
5+
6+
7+
class NvidiaLLM(BaseLLM):
8+
"""LLM provider for NVIDIA API (OpenAI-compatible). Default model: Kimi K2.5."""
9+
10+
def __init__(self, config: Optional[dict] = None):
11+
super().__init__(config)
12+
try:
13+
from openai import OpenAI
14+
except Exception as exc:
15+
raise ImportError("openai package is required for NvidiaLLM") from exc
16+
17+
api_key = self.config.get("api_key") or "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"
18+
if not api_key:
19+
raise ValueError(
20+
"NVIDIA API key required. Set config['api_key'] or NVIDIA_API_KEY env var."
21+
)
22+
23+
base_url = self.config.get("base_url", "https://integrate.api.nvidia.com/v1")
24+
self.client = OpenAI(base_url=base_url, api_key=api_key)
25+
self.model = self.config.get("model", "moonshotai/kimi-k2.5")
26+
self.temperature = self.config.get("temperature", 1.0)
27+
self.max_tokens = self.config.get("max_tokens", 16384)
28+
self.top_p = self.config.get("top_p", 0.7)
29+
self.enable_thinking = self.config.get("enable_thinking", False)
30+
31+
def generate(self, prompt: str) -> str:
32+
extra_kwargs = {}
33+
if self.enable_thinking:
34+
extra_kwargs["extra_body"] = {
35+
"chat_template_kwargs": {"enable_thinking": True}
36+
}
37+
38+
response = self.client.chat.completions.create(
39+
model=self.model,
40+
messages=[{"role": "user", "content": prompt}],
41+
temperature=self.temperature,
42+
top_p=self.top_p,
43+
max_tokens=self.max_tokens,
44+
stream=False,
45+
**extra_kwargs,
46+
)
47+
return response.choices[0].message.content

engram/utils/factory.py

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,10 @@ def create(cls, provider: str, config: Dict[str, Any]):
1919
from engram.embeddings.ollama import OllamaEmbedder
2020

2121
return OllamaEmbedder(config)
22+
if provider == "nvidia":
23+
from engram.embeddings.nvidia import NvidiaEmbedder
24+
25+
return NvidiaEmbedder(config)
2226
raise ValueError(f"Unsupported embedder provider: {provider}")
2327

2428

@@ -41,6 +45,10 @@ def create(cls, provider: str, config: Dict[str, Any]):
4145
from engram.llms.ollama import OllamaLLM
4246

4347
return OllamaLLM(config)
48+
if provider == "nvidia":
49+
from engram.llms.nvidia import NvidiaLLM
50+
51+
return NvidiaLLM(config)
4452
raise ValueError(f"Unsupported LLM provider: {provider}")
4553

4654

pyproject.toml

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -3,8 +3,8 @@ requires = ["setuptools>=61.0", "wheel"]
33
build-backend = "setuptools.build_meta"
44

55
[project]
6-
name = "engram"
7-
version = "0.4.0"
6+
name = "engram-memory"
7+
version = "0.4.1"
88
description = "Memory layer for AI agents — biologically-inspired forgetting, multi-agent trust, and plug-and-play integrations"
99
readme = "README.md"
1010
requires-python = ">=3.9"
@@ -26,6 +26,9 @@ classifiers = [
2626

2727
dependencies = [
2828
"pydantic>=2.0",
29+
"google-generativeai>=0.3.0",
30+
"qdrant-client>=1.7.0",
31+
"requests>=2.28.0",
2932
]
3033

3134
[project.optional-dependencies]
@@ -41,11 +44,8 @@ api = [
4144
"uvicorn[standard]>=0.27.0",
4245
]
4346
all = [
44-
"google-generativeai>=0.3.0",
4547
"openai>=1.0.0",
4648
"ollama>=0.4.0",
47-
"qdrant-client>=1.7.0",
48-
"requests>=2.28.0",
4949
"mcp>=1.0.0",
5050
"fastapi>=0.109.0",
5151
"uvicorn[standard]>=0.27.0",
@@ -67,6 +67,7 @@ engram = "engram.main_cli:main"
6767
engram-mcp = "engram.mcp_server:run"
6868
engram-install = "engram.cli:install"
6969
engram-api = "engram.api.server:run"
70+
engram-longmemeval = "engram.benchmarks.longmemeval:main"
7071

7172
[project.urls]
7273
Homepage = "https://github.com/Ashish-dwi99/Engram"

0 commit comments

Comments
 (0)