Skip to content

Commit 62ea7d9

Browse files
committed
Release 0.39.1 - Backend-agnostic public API docstrings
Remove ChromaDB, SQLite, MLX, and other implementation-specific references from public docstrings and API return values. The public API surface should be backend-agnostic for hosted service users.
1 parent 92ac972 commit 62ea7d9

9 files changed

Lines changed: 37 additions & 66 deletions

File tree

SKILL.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
---
22
name: keep
3-
version: 0.39.0
3+
version: 0.39.1
44
description: Reflective Memory
55
homepage: https://github.com/hughpyle/keep
66
runtime: python:3.12-slim

keep/__init__.py

Lines changed: 3 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -7,25 +7,15 @@
77
Quick Start:
88
from keep import Keeper
99
10-
kp = Keeper() # uses ~/.keep/ by default
10+
kp = Keeper()
1111
kp.update("file:///path/to/document.md", source_tags={"project": "myproject"})
1212
results = kp.find("something similar to this query")
1313
1414
CLI Usage:
1515
keep find "query text"
1616
keep put file:///path/to/doc.md -t category=docs
17-
keep collections --json
1817
19-
Default Store:
20-
~/.keep/ in the user's home directory (created automatically).
21-
Override with KEEP_STORE_PATH or explicit path argument.
22-
23-
Environment Variables:
24-
KEEP_STORE_PATH - Override default store location
25-
KEEP_OPENAI_API_KEY - API key for OpenAI providers
26-
27-
The store is initialized automatically on first use. Configuration is persisted
28-
in a TOML file within the store directory.
18+
The store is initialized automatically on first use.
2919
"""
3020

3121
# Configure quiet mode early (before any library imports)
@@ -47,7 +37,7 @@
4737
)
4838
from .types import Item, filter_non_system_tags, SYSTEM_TAG_PREFIX, INTERNAL_TAGS
4939

50-
__version__ = "0.39.0"
40+
__version__ = "0.39.1"
5141
__all__ = [
5242
"Keeper",
5343
"Item",

keep/api.py

Lines changed: 19 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -522,7 +522,7 @@ def _apply_file_size_limit(self, provider: DocumentProvider) -> None:
522522
p.max_size = max_size
523523

524524
def _check_store_consistency(self) -> bool:
525-
"""Check if DocumentStore and ChromaDB ID sets match.
525+
"""Check if document store and vector store ID sets match.
526526
527527
Returns True if reconciliation is needed. Does not fix —
528528
that is deferred to the first _upsert call when the
@@ -779,12 +779,8 @@ def _get_embedding_provider(self) -> EmbeddingProvider:
779779
"""
780780
Get embedding provider, creating it lazily on first use.
781781
782-
This allows read-only operations to work offline without loading
783-
the embedding model (which may try to reach HuggingFace).
784-
785-
For MLX (local GPU) providers, wraps with a lifecycle lock that
786-
serializes model access across processes to prevent GPU memory
787-
exhaustion.
782+
This allows read-only operations to work without loading
783+
the embedding model upfront.
788784
"""
789785
if self._embedding_provider is None:
790786
if self._config.embedding is None:
@@ -826,11 +822,7 @@ def _get_embedding_provider(self) -> EmbeddingProvider:
826822
return self._embedding_provider
827823

828824
def _get_summarization_provider(self) -> SummarizationProvider:
829-
"""
830-
Get summarization provider, creating it lazily on first use.
831-
832-
For MLX (local GPU) providers, wraps with a lifecycle lock.
833-
"""
825+
"""Get summarization provider, creating it lazily on first use."""
834826
if self._summarization_provider is None:
835827
registry = get_registry()
836828
provider = registry.create_summarization(
@@ -851,7 +843,6 @@ def _get_media_describer(self) -> Optional[MediaDescriber]:
851843
Get media describer, creating it lazily on first use.
852844
853845
Returns None if no media provider is configured or creation fails.
854-
For MLX (local GPU) providers, wraps with a lifecycle lock.
855846
"""
856847
if self._media_describer is None:
857848
if self._config.media is None:
@@ -949,7 +940,7 @@ def _validate_embedding_identity(self, provider: EmbeddingProvider) -> None:
949940
950941
On first use, records the embedding identity to config.
951942
On subsequent uses, if the provider changed, silently updates config
952-
and triggers background reindex into the new ChromaDB collection.
943+
and triggers background reindex into the new vector store collection.
953944
"""
954945
# Get current provider's identity
955946
current = EmbeddingIdentity(
@@ -982,7 +973,7 @@ def _validate_embedding_identity(self, provider: EmbeddingProvider) -> None:
982973
self._trigger_background_reindex()
983974

984975
def _trigger_background_reindex(self) -> None:
985-
"""Spawn background thread to populate new ChromaDB collection from DocumentStore."""
976+
"""Spawn background thread to populate new vector collection from document store."""
986977
import threading
987978
chroma_coll = self._resolve_chroma_collection()
988979
doc_coll = self._resolve_doc_collection()
@@ -1000,7 +991,7 @@ def _background_reindex_safe(self, chroma_coll: str, doc_coll: str) -> None:
1000991
logger.warning("Background reindex failed: %s", e)
1001992

1002993
def _background_reindex(self, chroma_coll: str, doc_coll: str) -> None:
1003-
"""Populate ChromaDB collection from DocumentStore summaries using batch embedding."""
994+
"""Populate vector collection from document store summaries using batch embedding."""
1004995
doc_ids = self._document_store.list_ids(doc_coll)
1005996
if not doc_ids:
1006997
return
@@ -1069,7 +1060,7 @@ def reindex(self) -> dict:
10691060
"""
10701061
Rebuild search index with current embedding provider (foreground).
10711062
1072-
Re-embeds all items from DocumentStore into the current ChromaDB
1063+
Re-embeds all items from the document store into the current vector
10731064
collection. Use as an explicit backstop when background reindex
10741065
didn't complete.
10751066
@@ -1142,7 +1133,7 @@ def embedding_identity(self) -> EmbeddingIdentity | None:
11421133
return self._config.embedding_identity
11431134

11441135
def _resolve_chroma_collection(self) -> str:
1145-
"""ChromaDB collection name derived from embedding identity."""
1136+
"""Vector collection name derived from embedding identity."""
11461137
if self._config.embedding_identity:
11471138
return self._config.embedding_identity.key
11481139
return "default"
@@ -1824,7 +1815,7 @@ def _rank_by_relevance(
18241815
"""
18251816
Rank candidate items by similarity to anchor + recency decay.
18261817
1827-
Uses stored embeddings from ChromaDB — no re-embedding needed.
1818+
Uses stored embeddings — no re-embedding needed.
18281819
Falls back to recency-only ranking if embeddings unavailable.
18291820
"""
18301821
import math
@@ -2029,7 +2020,7 @@ def get(self, id: str) -> Optional[Item]:
20292020
"""
20302021
Retrieve a specific item by ID.
20312022
2032-
Reads from document store (canonical), falls back to ChromaDB for legacy data.
2023+
Reads from document store (canonical), falls back to vector store for legacy data.
20332024
Touches accessed_at on successful retrieval.
20342025
"""
20352026
validate_id(id)
@@ -2593,7 +2584,7 @@ def count(self) -> int:
25932584
"""
25942585
Count items in a collection.
25952586
2596-
Returns count from document store if available, else ChromaDB.
2587+
Returns count from document store if available, else vector store.
25972588
"""
25982589
doc_coll = self._resolve_doc_collection()
25992590
chroma_coll = self._resolve_chroma_collection()
@@ -2814,17 +2805,17 @@ def reconcile(
28142805
fix: bool = False,
28152806
) -> dict:
28162807
"""
2817-
Check and optionally fix consistency between DocumentStore and ChromaDB.
2808+
Check and optionally fix consistency between document store and vector store.
28182809
28192810
Detects:
2820-
- Documents in DocumentStore missing from ChromaDB (not searchable)
2821-
- Documents in ChromaDB missing from DocumentStore (orphaned embeddings)
2811+
- Documents in document store missing from vector store (not searchable)
2812+
- Documents in vector store missing from document store (orphaned embeddings)
28222813
28232814
Args:
2824-
fix: If True, re-index documents missing from ChromaDB
2815+
fix: If True, re-index documents missing from vector store
28252816
28262817
Returns:
2827-
Dict with 'missing_from_chroma', 'orphaned_in_chroma', 'fixed' counts
2818+
Dict with 'missing_from_index', 'orphaned_in_index', 'fixed' counts
28282819
"""
28292820
doc_coll = self._resolve_doc_collection()
28302821
chroma_coll = self._resolve_chroma_collection()
@@ -2868,8 +2859,8 @@ def reconcile(
28682859
logger.warning("Failed to remove orphan %s: %s", orphan_id, e)
28692860

28702861
return {
2871-
"missing_from_chroma": len(missing_from_chroma),
2872-
"orphaned_in_chroma": len(orphaned_in_chroma),
2862+
"missing_from_index": len(missing_from_chroma),
2863+
"orphaned_in_index": len(orphaned_in_chroma),
28732864
"fixed": fixed,
28742865
"removed": removed,
28752866
"missing_ids": list(missing_from_chroma) if missing_from_chroma else [],

keep/backend.py

Lines changed: 3 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -2,8 +2,8 @@
22
Pluggable storage backend factory.
33
44
Creates storage backends (DocumentStore, VectorStore, PendingQueue) based on
5-
configuration. Local backends use SQLite + ChromaDB. External backends register
6-
via the ``keep.backends`` entry point group.
5+
configuration. External backends register via the ``keep.backends`` entry
6+
point group.
77
88
External backend packages provide a factory function::
99
@@ -59,9 +59,7 @@ def create_stores(config: StoreConfig) -> StoreBundle:
5959
"""
6060
Create storage backends from configuration.
6161
62-
For ``backend = "local"`` (default), creates SQLite DocumentStore,
63-
ChromaDB ChromaStore, and SQLite PendingSummaryQueue.
64-
62+
For ``backend = "local"`` (default), creates local storage backends.
6563
For other values, loads the backend via the ``keep.backends`` entry
6664
point group.
6765
"""

keep/config.py

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -135,7 +135,7 @@ class StoreConfig:
135135
# Remote backend (if set, Keeper delegates to keepnotes.ai API)
136136
remote: Optional[RemoteConfig] = None
137137

138-
# Pluggable backend ("local" = default SQLite+ChromaDB, or entry-point name)
138+
# Pluggable backend ("local" = default, or entry-point name)
139139
backend: str = "local"
140140
backend_params: dict[str, Any] = field(default_factory=dict)
141141

@@ -243,13 +243,13 @@ def detect_default_providers() -> dict[str, ProviderConfig | None]:
243243
Priority for embeddings:
244244
1. API keys: VOYAGE_API_KEY, OPENAI_API_KEY, GEMINI_API_KEY
245245
2. Ollama (if running locally with models)
246-
3. Local: MLX (Apple Silicon), sentence-transformers
246+
3. Local models (if installed)
247247
4. None if nothing available
248248
249249
Priority for summarization:
250250
1. API keys: ANTHROPIC_API_KEY (or CLAUDE_CODE_OAUTH_TOKEN), OPENAI_API_KEY, GEMINI_API_KEY
251251
2. Ollama (if running locally with a generative model)
252-
3. Local: MLX (Apple Silicon)
252+
3. Local models (if installed)
253253
4. Fallback: truncate (always available)
254254
255255
Returns provider configs for: embedding, summarization, document.

keep/data/openclaw-plugin/openclaw.plugin.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
"id": "keep",
33
"name": "keep",
44
"description": "Reflective memory — injects `keep now` context at agent start",
5-
"version": "0.39.0",
5+
"version": "0.39.1",
66
"configSchema": {
77
"type": "object",
88
"additionalProperties": false,

keep/data/openclaw-plugin/package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "keep",
3-
"version": "0.39.0",
3+
"version": "0.39.1",
44
"openclaw": {
55
"extensions": ["./index.ts"]
66
}

keep/protocol.py

Lines changed: 5 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,6 @@
44
Defines interface contracts at two levels:
55
- KeeperProtocol: the public API (CLI, RemoteKeeper)
66
- VectorStoreProtocol / DocumentStoreProtocol: internal storage backends
7-
(ChromaDB/SQLite locally, Postgres/pgvector in cloud)
87
"""
98

109
from typing import Any, Optional, Protocol, runtime_checkable
@@ -21,8 +20,8 @@ class KeeperProtocol(Protocol):
2120
The public interface for reflective memory operations.
2221
2322
Implemented by:
24-
- Keeper (local SQLite + ChromaDB backend)
25-
- RemoteKeeper (HTTP client to keepnotes.ai API)
23+
- Keeper (local backend)
24+
- RemoteKeeper (hosted keepnotes.ai API)
2625
"""
2726

2827
# -- Write operations --
@@ -187,9 +186,7 @@ class VectorStoreProtocol(Protocol):
187186
"""
188187
Abstract vector search backend.
189188
190-
Implemented by:
191-
- ChromaStore (local ChromaDB)
192-
- Cloud implementations (pgvector, Qdrant, etc.)
189+
Provides embedding storage, similarity search, and metadata queries.
193190
"""
194191

195192
# -- Embedding dimension --
@@ -302,9 +299,7 @@ class DocumentStoreProtocol(Protocol):
302299
"""
303300
Abstract document metadata backend.
304301
305-
Implemented by:
306-
- DocumentStore (local SQLite)
307-
- Cloud implementations (Postgres, etc.)
302+
Provides document storage, versioning, and tag-based queries.
308303
"""
309304

310305
# -- Write --
@@ -432,10 +427,7 @@ class PendingQueueProtocol(Protocol):
432427
"""
433428
Abstract pending summary queue.
434429
435-
Implemented by:
436-
- PendingSummaryQueue (local SQLite)
437-
- NullPendingQueue (no-op for backends that handle summarization server-side)
438-
- Cloud implementations (Postgres-backed queue, etc.)
430+
Manages background summarization of large content.
439431
"""
440432

441433
def enqueue(self, id: str, collection: str, content: str) -> None: ...

pyproject.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ build-backend = "hatchling.build"
44

55
[project]
66
name = "keep-skill"
7-
version = "0.39.0"
7+
version = "0.39.1"
88
description = "Reflective memory - remember and search documents by meaning"
99
readme = "README.md"
1010
requires-python = ">=3.11,<3.14"

0 commit comments

Comments
 (0)