# cascade-lattice

**Universal AI provenance + inference intervention. See what AI sees. Choose what AI chooses.**

[![PyPI](https://img.shields.io/pypi/v/cascade-lattice.svg)](https://pypi.org/project/cascade-lattice/)
[![Python](https://img.shields.io/pypi/pyversions/cascade-lattice.svg)](https://pypi.org/project/cascade-lattice/)
[![License](https://img.shields.io/badge/license-MIT-green.svg)](LICENSE)

```
pip install cascade-lattice
```

---

## Two Superpowers

### 1. OBSERVE - Cryptographic receipts for every AI call

```python
from cascade.store import observe

# Every inference -> hashed -> chained -> stored
receipt = observe("my_agent", {"action": "jump", "confidence": 0.92})
print(receipt.cid)  # bafyrei... (permanent content address)
```

### 2. HOLD - Pause AI at decision points

```python
from cascade.hold import Hold
import numpy as np

hold = Hold.get()

# In your inference loop:
action_probs = model.predict(state)  # Your model, any framework

resolution = hold.yield_point(
    action_probs=action_probs,
    action_names=["up", "down", "left", "right"]
)

# AI pauses. You see the decision matrix.
# Accept or override. Then it continues.
action = resolution.action
```

---

## Quick Start

### Zero-Config Auto-Patch

```python
import cascade
cascade.init()

# That's it. Every LLM call is now observed.
import openai
# ... use normally, receipts emit automatically
```

### Manual Observation

```python
from cascade.store import observe, query

# Write
observe("gpt-4", {"prompt": "Hello", "response": "Hi!", "tokens": 5})

# Read
for receipt in query("gpt-4", limit=10):
    print(receipt.cid, receipt.data)
```

### HOLD with 3D Visualization

```python
from cascade.hold import Hold, HoldMeshServer

# Start mesh server (serves 3D decision space)
server = HoldMeshServer(port=8766)
server.start()

# Open http://localhost:8766 in browser
# See action trajectories as 3D tubes!

hold = Hold.get()
# ... yield_point() calls update the visualization
```

---

## HOLD: Inference-Level Intervention

HOLD lets you pause any AI at decision points:

```
+-----------------------------------------------------+
|                 DECISION MATRIX                      |
+-----------------------------------------------------+
| [1] up      P=12.5%  ###                            |
| [2] down    P=37.9%  #########  <-- AI CHOICE       |
| [3] left    P=12.5%  ###                            |
| [4] right   P=37.1%  #########                      |
+-----------------------------------------------------+
|  [1-4] OVERRIDE    [ENTER] ACCEPT                   |
+-----------------------------------------------------+
```

**Model-agnostic** - works with:
- PyTorch, JAX, TensorFlow
- HuggingFace, OpenAI, Anthropic
- Stable Baselines, RLlib
- Any function that outputs probabilities

```python
# PyTorch
probs = torch.softmax(logits, dim=-1).numpy()

# HuggingFace
probs = model(**inputs).logits.softmax(-1).numpy()

# OpenAI (after getting logprobs)
probs = np.exp(logprobs)

# Then:
resolution = hold.yield_point(action_probs=probs)
```

---

## Collective Intelligence

Every observation goes into the **lattice** - a shared pool all agents can access:

```python
from cascade.store import observe, query

# Agent A observes
observe("pathfinder", {"state": [1,2], "action": 3, "reward": 1.0})

# Agent B queries (same or different machine!)
past = query("pathfinder")
for r in past:
    # Learn from collective experience
    print(r.data["action"], r.data["reward"])
```

**Optional HuggingFace sync** for cross-machine sharing:
```bash
# One-time setup (optional - everything works locally without this)
pip install huggingface-hub
huggingface-cli login
```

Without login, everything still works locally. The lattice is local-first.

---

## 3D Decision Visualization

HOLD can export decision spaces as **glTF** - the universal 3D format:

```python
from cascade.hold import HoldMeshServer

server = HoldMeshServer(port=8766)
server.start()

# Endpoints:
# GET /           - 3D viewer in browser
# GET /hold.glb   - glTF binary (import into Unity/Unreal/Godot)
# GET /hold.json  - Raw decision data
# WS  /stream     - Real-time updates
```

**Works with any game engine:**
- Unity: `GLTFUtility.LoadFromUrl("http://localhost:8766/hold.glb")`
- Unreal: HTTP request + glTF importer
- Godot: `GLTFDocument.append_from_file()`
- Blender: File > Import > glTF

---

## CLI

```bash
# View your lattice
cascade stats

# List observations  
cascade list --model my_agent

# Start proxy (observe any app)
cascade proxy --port 7777

# Sync to HuggingFace (optional)
cascade sync
```

---

## Installation Options

```bash
# Core (observation + HOLD)
pip install cascade-lattice

# With LLM providers
pip install cascade-lattice[openai]
pip install cascade-lattice[anthropic]
pip install cascade-lattice[all]

# With HuggingFace sync
pip install cascade-lattice[huggingface]
```

---

## How It Works

```
Your Model                    CASCADE                      Storage
    |                            |                            |
    |  action_probs = [0.1,     |                            |
    |                  0.6,     |                            |
    |                  0.3]     |                            |
    | ------------------------->|                            |
    |                           |  hash(probs) -> CID        |
    |        HOLD               |  chain(prev_cid, cid)      |
    |   +-------------+         | -------------------------> |
    |   | See matrix  |         |              ~/.cascade/   |
    |   | Override?   |         |              lattice/      |
    |   +-------------+         |                            |
    | <-------------------------|                            |
    |   resolution.action       |                            |
```

---

## Why CASCADE?

| Problem | CASCADE Solution |
|---------|-----------------|
| "What was the AI thinking?" | HOLD shows the full decision matrix |
| "Can I override AI decisions?" | Yes, at inference level |
| "Prove model X made output Y" | Cryptographic receipt with CID |
| "Share learning across agents" | Collective lattice, queryable |
| "Visualize decisions in game" | glTF export, works everywhere |

---

## Genesis

Every receipt chains back to genesis:

```
Genesis: 89f940c1a4b7aa65
IPFS: bafkreidixjlzdat7ex72foi6vm3vnskhzguovxj6ondbazrqks7v6ahmei
```

The lattice grows. Discovery is reading the chain.

---

## Links

- [Demo](https://huggingface.co/spaces/tostido/Cascade)
- [Source](https://huggingface.co/spaces/tostido/Cascade/tree/main)

---

*"even still, i grow, and yet, I grow still"*
