Metadata-Version: 2.4
Name: tigunny-memory
Version: 0.1.0
Summary: Governance-aware agent memory with semantic recall, hash-chained audit, and swarm sync
Project-URL: Homepage, https://github.com/tigunny/tigunny-memory
Project-URL: Documentation, https://github.com/tigunny/tigunny-memory#readme
Project-URL: Repository, https://github.com/tigunny/tigunny-memory
Project-URL: Issues, https://github.com/tigunny/tigunny-memory/issues
Author-email: Tigunny LLC <dev@tigunny.com>
License-Expression: Apache-2.0
Keywords: agent,ai,audit,embeddings,governance,llm,memory,qdrant,rag
Classifier: Development Status :: 4 - Beta
Classifier: Framework :: AsyncIO
Classifier: Intended Audience :: Developers
Classifier: License :: OSI Approved :: Apache Software License
Classifier: Programming Language :: Python :: 3
Classifier: Programming Language :: Python :: 3.11
Classifier: Programming Language :: Python :: 3.12
Classifier: Programming Language :: Python :: 3.13
Classifier: Topic :: Scientific/Engineering :: Artificial Intelligence
Classifier: Topic :: Software Development :: Libraries :: Python Modules
Classifier: Typing :: Typed
Requires-Python: >=3.11
Requires-Dist: cryptography>=42.0.0
Requires-Dist: httpx>=0.27.0
Requires-Dist: pydantic>=2.7.0
Requires-Dist: python-dotenv>=1.0.0
Requires-Dist: qdrant-client>=1.9.0
Provides-Extra: all
Requires-Dist: alembic>=1.13.0; extra == 'all'
Requires-Dist: anthropic>=0.28.0; extra == 'all'
Requires-Dist: asyncpg>=0.29.0; extra == 'all'
Requires-Dist: ollama>=0.2.0; extra == 'all'
Requires-Dist: openai>=1.30.0; extra == 'all'
Requires-Dist: redis>=5.0.0; extra == 'all'
Requires-Dist: voyageai>=0.2.0; extra == 'all'
Provides-Extra: dev
Requires-Dist: build>=1.2.0; extra == 'dev'
Requires-Dist: mypy>=1.10.0; extra == 'dev'
Requires-Dist: pytest-asyncio>=0.23.0; extra == 'dev'
Requires-Dist: pytest-cov>=5.0.0; extra == 'dev'
Requires-Dist: pytest>=8.0.0; extra == 'dev'
Requires-Dist: ruff>=0.4.0; extra == 'dev'
Requires-Dist: twine>=5.0.0; extra == 'dev'
Provides-Extra: ollama
Requires-Dist: ollama>=0.2.0; extra == 'ollama'
Provides-Extra: openai
Requires-Dist: openai>=1.30.0; extra == 'openai'
Provides-Extra: postgres
Requires-Dist: alembic>=1.13.0; extra == 'postgres'
Requires-Dist: asyncpg>=0.29.0; extra == 'postgres'
Provides-Extra: redis
Requires-Dist: redis>=5.0.0; extra == 'redis'
Provides-Extra: security
Requires-Dist: anthropic>=0.28.0; extra == 'security'
Provides-Extra: voyage
Requires-Dist: voyageai>=0.2.0; extra == 'voyage'
Description-Content-Type: text/markdown

# tigunny-memory

[![PyPI version](https://img.shields.io/pypi/v/tigunny-memory)](https://pypi.org/project/tigunny-memory/)
[![Python versions](https://img.shields.io/pypi/pyversions/tigunny-memory)](https://pypi.org/project/tigunny-memory/)
[![License](https://img.shields.io/badge/license-Apache%202.0-blue)](LICENSE)
[![Tests](https://img.shields.io/github/actions/workflow/status/tigunny/tigunny-memory/test.yml?label=tests)](https://github.com/tigunny/tigunny-memory/actions)

**Governance-aware agent memory with semantic recall, hash-chained audit, and swarm sync.**

Drop production-grade memory into any AI agent project in under 5 minutes. Built for teams that need audit trails, PII protection, and multi-agent coordination out of the box.

## Why tigunny-memory?

| Raw Qdrant | tigunny-memory |
|------------|----------------|
| Manual tenant filtering | **Structural tenant isolation** — impossible to bypass |
| No PII protection | **DLP scanner** blocks SSNs, credit cards, API keys automatically |
| No audit trail | **Hash-chained audit log** — tamper-evident, SIEM-exportable |
| Static similarity ranking | **Outcome-weighted recall** — agents learn which memories actually helped |
| Single-agent only | **Swarm sync** — agents share discoveries via Redis pub/sub |
| DIY injection protection | **Prompt injection detector** with fast patterns + semantic scan |

## Quick Start

```bash
pip install tigunny-memory
docker run -p 6333:6333 qdrant/qdrant
tigunny-memory init
```

```python
from tigunny_memory import TigunnyMemory, MemoryConfig

config = MemoryConfig.from_env()

async with TigunnyMemory(config) as mem:
    # Store a memory
    entry = await mem.store(
        agent_id="research-agent",
        content={"task": "market analysis", "result": "Q4 revenue grew 23%"},
        tags=["research", "finance"],
    )

    # Recall relevant memories
    results = await mem.recall("research-agent", "What do we know about revenue?")
    for r in results:
        print(f"[{r.weighted_score:.2f}] {r.memory.content}")

    # Record outcome — improves future recall ranking
    await mem.learn("research-agent", entry.memory_id, outcome_score=0.9)
```

## Installation

```bash
# Core (Ollama embeddings, Qdrant, file-based audit)
pip install tigunny-memory

# With specific providers
pip install tigunny-memory[openai]       # OpenAI embeddings
pip install tigunny-memory[voyage]       # Voyage AI embeddings
pip install tigunny-memory[redis]        # Multi-agent swarm sync
pip install tigunny-memory[postgres]     # PostgreSQL audit backend
pip install tigunny-memory[security]     # Semantic injection detection

# Everything
pip install tigunny-memory[all]
```

| Extra | What it enables | Required for |
|-------|----------------|--------------|
| `openai` | OpenAI text-embedding-3 models | `EmbeddingProvider.OPENAI` |
| `ollama` | Ollama SDK (httpx used by default) | Optional Ollama features |
| `voyage` | Voyage AI embeddings | `EmbeddingProvider.VOYAGE` |
| `postgres` | PostgreSQL audit log backend | `audit_db_url` config |
| `redis` | Redis pub/sub swarm sync | `enable_swarm_sync=True` |
| `security` | Claude-based semantic injection scan | Enhanced injection detection |
| `all` | All of the above | Full feature set |
| `dev` | pytest, ruff, mypy, build tools | Contributing |

## Configuration

All fields can be set via `MemoryConfig` or environment variables:

```python
config = MemoryConfig(
    qdrant_url="http://localhost:6333",
    embedding_provider=EmbeddingProvider.OLLAMA,
    tenant_id="my-project",
    max_ttl_days=90,
    enable_dlp=True,
    enable_audit_chain=True,
    enable_injection_detection=True,
    recall_top_k=10,
    outcome_weight=0.3,
)

# Or from environment:
config = MemoryConfig.from_env()  # reads TIGUNNY_MEMORY_* env vars
```

| Env Variable | Default | Description |
|-------------|---------|-------------|
| `TIGUNNY_MEMORY_QDRANT_URL` | `http://localhost:6333` | Qdrant server URL |
| `TIGUNNY_MEMORY_EMBEDDING_PROVIDER` | `ollama` | `openai`, `ollama`, `voyage`, `custom` |
| `TIGUNNY_MEMORY_TENANT_ID` | `default` | Multi-tenant isolation key |
| `TIGUNNY_MEMORY_OPENAI_API_KEY` | - | Required for OpenAI embeddings |
| `TIGUNNY_MEMORY_ENABLE_DLP` | `true` | PII/credential scanning |
| `TIGUNNY_MEMORY_ENABLE_AUDIT_CHAIN` | `true` | Hash-chained audit log |
| `TIGUNNY_MEMORY_OUTCOME_WEIGHT` | `0.3` | Outcome influence on recall ranking |

## Embedding Providers

| Provider | Install | Dimensions | Cost | Best for |
|----------|---------|------------|------|----------|
| Ollama | `pip install tigunny-memory` | 768 | Free | Dev, air-gapped |
| OpenAI Small | `pip install tigunny-memory[openai]` | 1,536 | ~$0.02/1M tokens | Production |
| OpenAI Large | `pip install tigunny-memory[openai]` | 3,072 | ~$0.13/1M tokens | High accuracy |
| Voyage 3 | `pip install tigunny-memory[voyage]` | 1,024 | ~$0.06/1M tokens | Retrieval-optimized |
| Custom | `pip install tigunny-memory` | Configurable | Varies | Azure, vLLM, LM Studio |

## Governance

tigunny-memory enforces governance rules on every operation — no opt-out:

- **DLP Scanner**: Blocks PII (emails, SSNs, credit cards) and silently redacts API keys/credentials before they reach the vector store
- **TTL Enforcement**: Memories auto-expire after configurable retention period (default 90 days)
- **Size Limits**: Prevents memory bloat with configurable content size caps
- **Tenant Isolation**: Structural filter on every Qdrant query — tenants cannot see each other's data even on misconfiguration

All governance rules work with **zero configuration** using sensible defaults.

## Audit Trail

Every operation writes to a hash-chained audit log (like a blockchain for your agent's memory):

```python
# Verify chain integrity
result = await mem.verify_integrity()
# {"valid": True, "checked": 1247, "broken_at_sequence": None}

# Export for SIEM ingestion
blocks = await mem.export_audit(output_path="./audit.ndjson")
```

Audit backends:
- **File** (default): NDJSON file, works anywhere, no DB required
- **PostgreSQL** (optional): `pip install tigunny-memory[postgres]`, set `audit_db_url`

## Multi-Agent Swarm Sync

```bash
pip install tigunny-memory[redis]
```

```python
config = MemoryConfig(
    enable_swarm_sync=True,
    redis_url="redis://localhost:6379",
    tenant_id="my-project",
)

async with TigunnyMemory(config) as mem:
    # Agent A stores a discovery — all agents in the swarm are notified
    await mem.store("agent-a", {"finding": "competitor launched new product"}, tags=["intel"])

    # Agent B receives the notification and can pull from Qdrant
    # Discovery events share metadata only — not full content (security by design)
```

Without Redis, `NoopSwarmSync` is used — zero overhead, no errors.

## CLI Reference

```bash
tigunny-memory version    # Version + installed optional deps
tigunny-memory health     # Check Qdrant, embeddings, audit backends
tigunny-memory init       # Interactive setup wizard
tigunny-memory store      # --agent <id> --content '{"key":"value"}'
tigunny-memory recall     # --agent <id> --query "search query"
tigunny-memory audit verify   # Verify hash-chain integrity
tigunny-memory audit export   # Export audit log to NDJSON
tigunny-memory stats      # Learning statistics
```

## Framework Integration

### FastAPI

```python
from contextlib import asynccontextmanager
from fastapi import FastAPI, Depends
from tigunny_memory import TigunnyMemory, MemoryConfig

memory: TigunnyMemory | None = None

@asynccontextmanager
async def lifespan(app: FastAPI):
    global memory
    memory = TigunnyMemory(MemoryConfig.from_env())
    await memory.connect()
    yield
    await memory.close()

app = FastAPI(lifespan=lifespan)

@app.post("/agent/execute")
async def execute(agent_id: str, task: str):
    relevant = await memory.recall(agent_id, task)
    # ... call LLM with context from relevant memories ...
    entry = await memory.store(agent_id, {"task": task, "result": result})
    return {"memory_id": entry.memory_id}
```

## Security

- **Prompt injection detection**: Fast regex patterns catch common attacks instantly. Optional semantic scan via Claude Haiku provides deeper analysis.
- **Fail-closed**: If semantic scan fails (API error), content is **blocked**, not allowed.
- **Memory sanitizer**: Every write passes through injection + DLP checks before reaching Qdrant.
- **Content hashing**: SHA-256 hash of every stored memory for integrity verification.

Enable semantic injection detection:

```bash
pip install tigunny-memory[security]
export TIGUNNY_MEMORY_ANTHROPIC_API_KEY=sk-ant-...
export TIGUNNY_MEMORY_ENABLE_INJECTION_DETECTION=true
```

## License

Apache 2.0

Built by **Tigunny LLC** — SDVOSB · TX HUB Certified.
