Metadata-Version: 2.4
Name: kmf
Version: 1.0.3
Summary: KMF — Knowledge Memory Format: portable, local, versioned AI memory
Author: KMF Contributors
License: MIT
Keywords: ai,memory,llm,knowledge,format,mcp,claude,langchain
Classifier: Development Status :: 5 - Production/Stable
Classifier: Intended Audience :: Developers
Classifier: License :: OSI Approved :: MIT License
Classifier: Programming Language :: Python :: 3
Classifier: Programming Language :: Python :: 3.10
Classifier: Programming Language :: Python :: 3.11
Classifier: Programming Language :: Python :: 3.12
Classifier: Topic :: Scientific/Engineering :: Artificial Intelligence
Classifier: Topic :: Software Development :: Libraries :: Python Modules
Classifier: Typing :: Typed
Requires-Python: >=3.10
Description-Content-Type: text/markdown
License-File: LICENSE
Requires-Dist: pydantic>=2.0
Requires-Dist: python-ulid>=2.0
Requires-Dist: rich>=13.0
Requires-Dist: click>=8.0
Provides-Extra: semantic
Requires-Dist: sentence-transformers>=2.2; extra == "semantic"
Provides-Extra: langchain
Requires-Dist: langchain-core>=0.1; extra == "langchain"
Provides-Extra: all
Requires-Dist: sentence-transformers>=2.2; extra == "all"
Requires-Dist: langchain-core>=0.1; extra == "all"
Provides-Extra: dev
Requires-Dist: pytest>=7.0; extra == "dev"
Requires-Dist: pytest-cov>=4.0; extra == "dev"
Requires-Dist: build>=1.0; extra == "dev"
Requires-Dist: twine>=4.0; extra == "dev"
Dynamic: license-file

# KMF — Knowledge Memory Format

**Portable, local, versioned AI memory. v1.0**

KMF is an open format and Python library for structured AI memory. It solves the problem that current AI systems either have no persistent memory, or store everything as unstructured text blobs with no provenance, policy, or control.

---

## Merging Repositories

```bash
# Merge two repos (e.g. work laptop + home laptop)
kmf merge work.kmf home.kmf --output merged.kmf

# Dry run — see what would change
kmf merge work.kmf home.kmf --dry-run

# Merge only specific scopes
kmf merge personal.kmf colleague.kmf --scopes work
```

```python
base = KMF.load("work.kmf")
home = KMF.load("home.kmf")
result = base.merge(home)
print(result.summary())
base.save("merged.kmf")
```

Merge strategy: same ID → newer wins. Conflicting facts (same subject+predicate, different value) → Conflict object created. Preferences → newer wins.

---

## LangChain Integration

```bash
pip install "kmf[langchain]"
```

```python
from langchain.chains import ConversationChain
from langchain_openai import ChatOpenAI
from kmf.integrations.langchain import KMFMemory, KMFRetriever

# Drop-in memory replacement
memory = KMFMemory.from_file("personal.kmf", api_key="sk-ant-...")
chain = ConversationChain(llm=ChatOpenAI(), memory=memory)
chain.predict(input="What did we decide about the database?")
# → loads KMF context, answers, stores new memory after each turn

# Retriever for RAG chains
retriever = KMFRetriever.from_file("personal.kmf")
docs = retriever.get_relevant_documents("Python architecture")
```

---

## Semantic Search

KMF uses local embeddings for recall — no cloud, no API key needed.

```bash
# Install (one-time, ~80MB model download)
pip install "kmf[semantic]"

# Build index
kmf index personal.kmf
```

After indexing, `recall()` automatically uses semantic similarity instead of keyword matching. If `sentence-transformers` is not installed, KMF silently falls back to keyword search — nothing breaks.

**Default model:** `all-MiniLM-L6-v2` — fast on CPU, works well in German and English.

```python
# Custom model
kmf = KMF.load("personal.kmf")
bundle = kmf.recall("what did we decide about the database?")
# → uses semantic search if indexed, keywords otherwise
```

---

## MCP Server (Claude Desktop / claude.ai)

KMF ships a built-in MCP server. Once configured, Claude automatically has access to your memory — no manual context injection needed.

### Setup

**1. Add to `claude_desktop_config.json`:**

```json
{
  "mcpServers": {
    "kmf": {
      "command": "kmf",
      "args": ["mcp", "/path/to/personal.kmf"]
    }
  }
}
```

macOS: `~/Library/Application Support/Claude/claude_desktop_config.json`
Windows: `%APPDATA%\Claude\claude_desktop_config.json`

**2. Restart Claude Desktop.** KMF tools appear automatically.

### Available Tools

| Tool | What it does |
|---|---|
| `kmf_recall` | Load relevant memory context for a query |
| `kmf_remember` | Store a fact, preference, or decision directly |
| `kmf_ingest_text` | Extract and store memory from a conversation |
| `kmf_forget` | Archive (soft-delete) an outdated memory |
| `kmf_stats` | Repository statistics |
| `kmf_conflicts` | List unresolved contradictions |

### Workflow

```
Start of conversation:
  → Claude calls kmf_recall("user preferences and recent decisions")
  → Gets compact TOON context block (~200-500 tokens vs 2000+ raw)

During conversation:
  → Nothing — chat as normal

End of conversation:
  → Claude calls kmf_ingest_text(transcript) using Haiku
  → New facts/decisions stored for next time
```

---

## Install

```bash
pip install kmf
```

Or from source:

```bash
git clone https://github.com/you/kmf
cd kmf
pip install -e .
```

---

## Quick Start

```python
from kmf import KMF, SessionInput

# Create a repository
kmf = KMF.create("personal")

# Consolidate a session into memory
session = SessionInput(
    title="Architecture discussion",
    summary_short="Decided on local-first approach",
    proposed_facts=[{
        "subject": "project",
        "predicate": "architecture",
        "object": "local-first",
        "confidence": 0.95,
        "writer": "explicit_user_statement",
    }],
    proposed_preferences=[{
        "domain": "language",
        "key": "response_language",
        "value": "de",
        "strength": "strong",
        "writer": "explicit_user_statement",
    }],
    proposed_decisions=[{
        "title": "Local-first Architecture",
        "decision": "Repository lives locally with the user",
        "rationale": ["Control", "Portability", "Privacy"],
        "tradeoffs": ["Sync complexity"],
        "confidence": 0.95,
        "writer": "explicit_user_statement",
    }],
)
result = kmf.consolidate(session)

# Recall context for a query (token-budgeted)
bundle = kmf.recall("what did we decide about the architecture?")
print(bundle.rendered)

# Save to file
kmf.save("personal.kmf")

# Load later
kmf = KMF.load("personal.kmf")
```

**Output:**
```
[MEMORY CONTEXT — bundle:ctx_... — scopes: — budget:2000tok]

[PROFILE]
prefs[1]{domain,key,value,strength}:
language,response_language,de,strong

[FACTS]
facts[1]{subject,predicate,object,conf}:
project,architecture,local-first,0.95

[DECISIONS]
decisions[1]{title,decision,conf}:
Local-first Architecture,Repository lives locally with the user,0.95

[RECENT EPISODES]
• Architecture discussion: Decided on local-first approach

[/MEMORY CONTEXT]
```

---

## CLI

```bash
# Create a new repository
kmf init personal --description "My personal memory"

# Consolidate a session JSON file
kmf consolidate personal.kmf session.json

# Recall context for a query
kmf recall personal.kmf "what did we decide about the database?"

# List objects
kmf list personal.kmf --type fact

# Show history
kmf history personal.kmf

# Stats
kmf stats personal.kmf
```

---

## Core Concepts

### Objects

Every memory item is a structured object with metadata:

| Type | Purpose |
|---|---|
| `episode` | A completed session or interaction |
| `fact` | A declarative statement with subject/predicate/object |
| `preference` | A user preference |
| `decision` | A decision with rationale and alternatives |
| `entity` | A named entity (person, project, concept) |
| `summary` | A condensed view of other objects |
| `conflict` | An explicit contradiction between two objects |
| `rule` | A user-defined policy |

Every object carries: `confidence`, `importance`, `sensitivity`, `provenance`, `permissions`, `valid_time`.

### Key Principles

**Storing ≠ Prompting** — An object can be stored but never sent to a prompt. Three separate permission layers.

**Consolidation is separate from chat** — The chat produces raw signal. A post-session consolidation process decides what persists. This prevents contamination from smalltalk, irony, or model errors.

**Conflicts are explicit** — When two facts contradict each other, a `conflict` object is created and surfaced in recall. No silent overwrites.

**Local-first** — The repository lives with the user. Cloud sync is optional, not the default.

### TOON Format

Prompt bundles use TOON (Token-Optimized Output Notation) instead of JSON — saving 30–85% tokens for tabular data:

```
# JSON: ~580 tokens
# TOON: ~85 tokens for the same 3 decisions

decisions[3]{title,decision,conf}:
Local-first Architecture,Repository lies locally with the user,0.95
Dual-Format JSON+TOON,JSON in store / TOON in prompt,0.92
Consolidation separate from chat,No direct writes from chat,0.90
```

---

## Session JSON Format

```json
{
  "title": "Session title",
  "summary_short": "One-line summary",
  "summary_long": "Longer summary",
  "topics": ["topic1", "topic2"],
  "proposed_facts": [
    {
      "subject": "project",
      "predicate": "uses",
      "object": "PostgreSQL",
      "confidence": 0.9,
      "writer": "explicit_user_statement"
    }
  ],
  "proposed_preferences": [
    {
      "domain": "style",
      "key": "format",
      "value": "direct, no filler",
      "strength": "strong",
      "writer": "explicit_user_statement"
    }
  ],
  "proposed_decisions": [
    {
      "title": "Decision title",
      "decision": "What was decided",
      "rationale": ["reason 1", "reason 2"],
      "tradeoffs": ["tradeoff 1"],
      "confidence": 0.95,
      "writer": "explicit_user_statement"
    }
  ],
  "proposed_entities": [
    {
      "entity_type": "project",
      "canonical_name": "Project Alpha",
      "aliases": ["alpha"],
      "confidence": 0.95
    }
  ]
}
```

---

## Architecture

```
KMF
├── models/        Pydantic object models (KMFObject, Chunk, Commit, Manifest)
├── storage/       SQLite-backed repository with .kmf import/export
├── recall/        7-stage recall pipeline with scoring formula
├── consolidation/ Post-session engine: raw input → persistent objects
├── render/        TOON renderer for prompt bundles
├── policy/        Sensitivity and access control
└── cli/           Command-line interface
```

### Recall Scoring

```
score = semantic_relevance * 0.35
      + importance         * 0.20
      + confidence         * 0.15
      + recency            * 0.15
      + scope_match        * 0.10
      - sensitivity_penalty * 0.05
```

---

## Roadmap

- [ ] v0.2: Embedding-based semantic search (model-agnostic)
- [ ] v0.2: Multi-device sync protocol
- [ ] v0.3: Multimodal support (image captions, audio transcripts)
- [ ] v0.3: LangChain / LlamaIndex integration
- [ ] v1.0: Formal interoperability standard

---

## License

MIT

---

*KMF is an open specification. No company, no lock-in. The goal: a common standard for portable AI memory.*
