Metadata-Version: 2.4
Name: semantic-buffer
Version: 0.1.2
Summary: A lightweight, local-first semantic memory buffer for AI agents with hybrid time-decay scoring.
Author-email: Your Name <your.email@example.com>
License-Expression: MIT
License-File: LICENSE
Keywords: agents,ai,memory,rag,semantic-search,sqlite
Classifier: License :: OSI Approved :: MIT License
Classifier: Operating System :: OS Independent
Classifier: Programming Language :: Python :: 3
Classifier: Topic :: Scientific/Engineering :: Artificial Intelligence
Requires-Python: >=3.9
Requires-Dist: numpy>=1.20.0
Provides-Extra: dev
Requires-Dist: build>=1.0.0; extra == 'dev'
Requires-Dist: pytest>=7.0.0; extra == 'dev'
Requires-Dist: ruff>=0.1.0; extra == 'dev'
Requires-Dist: twine>=4.0.0; extra == 'dev'
Provides-Extra: local
Requires-Dist: sentence-transformers>=2.2.0; extra == 'local'
Description-Content-Type: text/markdown

# semantic-buffer 🧠

[![PyPI version](https://img.shields.io/pypi/v/semantic-buffer.svg)](https://pypi.org/project/semantic-buffer/)
[![Python versions](https://img.shields.io/pypi/pyversions/semantic-buffer.svg)](https://pypi.org/project/semantic-buffer/)
[![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](https://opensource.org/licenses/MIT)

A lightweight, local-first semantic memory buffer for AI agents. It implements a hybrid scoring system that prioritizes memories based on **semantic relevance**, **importance**, and **exponential time-decay (recency)**.

## 🌟 Features
- **Local-first Vector Storage**: Simple SQLite-based vector storage with zero cloud dependencies or bulky database installations.
- **Hybrid Scoring**: Combines cosine similarity, recency (exponential time decay), and importance weighting to retrieve the most contextual memories.
- **Pluggable Embeddings**: Run lightweight model locally (`sentence-transformers`) or plug in any API (Gemini, OpenAI, Cohere).
- **Agent Decorators**: `@remember` decorator automatically tracks function inputs, returns, and metadata in the background.

## 🏗️ Architecture

```text
  [ Agent Action ] ──► ( @remember Decorator ) ──► [ SemanticBuffer ]
                                                           │
                                                  ( Generate Embeddings )
                                                           │
          [ LLM Prompt ] ◄── [ Ranked Top N Memories ] ◄── [ SQLite DB ]
```

## 🚀 Installation & Import Namespace

> [!IMPORTANT]
> **Install Name vs. Import Name Namespace**
> - **Pip Install Name**: `semantic-buffer` (with hyphen)
> - **Python Import Name**: `semanticbuffer` (no hyphens or underscores, e.g. `import semanticbuffer`)

### 1. Minimal Installation (API Embedders)
If you only plan to use external API models (Gemini, OpenAI, etc.) and want to keep dependencies lightweight:
```bash
pip install semantic-buffer
```

### 2. Local-First Installation (Offline CPU Models)
If you want to use the default offline embeddings (`sentence-transformers` running locally on your CPU):
```bash
pip install "semantic-buffer[local]"
```

> [!WARNING]
> If you instantiate `SemanticBuffer()` without passing an embedder, it defaults to using the local offline model. If you did not install the `[local]` extra, it will throw an `ImportError` requesting `sentence-transformers`.


## ⚡ Quickstart

```python
from semanticbuffer import SemanticBuffer

# 1. Initialize local memory buffer
buffer = SemanticBuffer(db_path="my_memory.db")

# 2. Add memories with importance scores
buffer.add("User's favorite programming language is Python.", importance=0.9)
buffer.add("It rained today in Paris.", importance=0.4)

# 3. Retrieve relevant context dynamically
memories = buffer.search("What coding preferences does the user have?", limit=1)
print(memories[0]["content"])
# Output: "User's favorite programming language is Python."
```

### Auto-Capture Agent Interactions with Decorators

```python
buffer = SemanticBuffer()

@buffer.remember(importance=0.7)
def run_web_search(query: str):
    # Mocking search execution
    return f"Results for {query}: Python is a versatile language."

# Automatically logged to database
run_web_search("Python info")
```

## ⚙️ Custom Embedders (OpenAI Example)
You can easily swap out the local model for your preferred embedding API:

```python
from semanticbuffer import SemanticBuffer, BaseEmbedder

class OpenAIEmbedder(BaseEmbedder):
    def __init__(self, api_key):
        from openai import OpenAI
        self.client = OpenAI(api_key=api_key)

    def embed_query(self, text: str):
        res = self.client.embeddings.create(input=[text], model="text-embedding-3-small")
        return res.data[0].embedding

    def embed_documents(self, texts: list[str]):
        return [self.embed_query(t) for t in texts]

# Instantiate with custom embedder
buffer = SemanticBuffer(embedder=OpenAIEmbedder(api_key="your-key"))
```

## 📄 License
This project is licensed under the MIT License - see the LICENSE file for details.
