Metadata-Version: 2.4
Name: latticing
Version: 0.1.2
Summary: Using Behavior Latticing to infer user motivation from unstructured interactions
License: MIT License
        
        Copyright (c) 2026 Stanford HCI
        
        Permission is hereby granted, free of charge, to any person obtaining a copy
        of this software and associated documentation files (the "Software"), to deal
        in the Software without restriction, including without limitation the rights
        to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
        copies of the Software, and to permit persons to whom the Software is
        furnished to do so, subject to the following conditions:
        
        The above copyright notice and this permission notice shall be included in all
        copies or substantial portions of the Software.
        
        THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
        IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
        FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
        AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
        LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
        OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
        SOFTWARE.
License-File: LICENSE
Requires-Python: >=3.10
Requires-Dist: anthropic>=0.96.0
Requires-Dist: build>=1.4.4
Requires-Dist: dotenv>=0.9.9
Requires-Dist: google-genai>=1.47.0
Requires-Dist: openai>=2.32.0
Requires-Dist: plotly>=5.0.0
Requires-Dist: pyyaml>=6.0.3
Requires-Dist: tenacity>=9.1.2
Requires-Dist: together>=2.9.0
Requires-Dist: twine>=6.2.0
Provides-Extra: dev
Requires-Dist: pytest-cov; extra == 'dev'
Requires-Dist: pytest>=7.0; extra == 'dev'
Description-Content-Type: text/markdown

# Behavior Latticing

[![Python 3.10+](https://img.shields.io/badge/python-3.10+-blue.svg)](https://www.python.org/downloads/)
[![arXiv](https://img.shields.io/badge/arXiv-2604.07629-b31b1b.svg)](https://arxiv.org/abs/2604.07629)
[![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](LICENSE)

**Latticing** is a Python library for transforming raw interaction traces into behavioral insights about the user's motivations.

Given a stream of user interactions — chat histories, screen activity logs, support tickets, behavior latticing induces user motivation through hierarchically grouping and interpreting user behavior. 

## Installation

```bash
pip install latticing
```

Set your LLM provider API key(s) in a `.env` file or your environment:

```bash
ANTHROPIC_API_KEY=sk-ant-...   # Anthropic (Claude)
OPENAI_API_KEY=sk-...          # OpenAI (GPT)
GOOGLE_API_KEY=...             # Google (Gemini)
TOGETHER_API_KEY=...           # Together AI
```

**Requirements:** Python 3.10+

## Quick start

```python
import os
import asyncio
from lattice import Lattice, AsyncLLM, SyncLLM
from dotenv import load_dotenv

load_dotenv()

# interaction_traces: list of sessions, each a dict with
# "interactions" (list of {interaction, metadata}) and "time"
l = Lattice(
    name="Alice",
    interactions=interaction_traces,
    description="the user's ChatGPT conversations",
    insight_model=AsyncLLM(name="claude-opus-4-6", api_key=os.getenv("ANTHROPIC_API_KEY")),
    observer_model=AsyncLLM(name="claude-sonnet-4-6", api_key=os.getenv("ANTHROPIC_API_KEY")),
    evidence_model=AsyncLLM(name="claude-sonnet-4-6", api_key=os.getenv("ANTHROPIC_API_KEY")),
    format_model=SyncLLM(name="claude-sonnet-4-6", api_key=os.getenv("ANTHROPIC_API_KEY")),
    params={"max_concurrent": 100, "min_insights": 3, "window_size": 100},
)

# Each config entry defines a layer: how to group inputs into insight clusters
config = {
    0: {"type": "session", "value": "5"},   # L1: synthesize observations across 5 chunks (i.e., chat conversations)
    1: {"type": "session", "value": "10"},  # L2: synthesize insights across 10 chunks from the layer below
}

asyncio.run(l.build(config))
l.save("lattice.json")

# Interactive Plotly figure
l.visualize().show()
```

## How it works

1. **Observe** — the `Observer` reads sliding windows of raw interactions and prompts an LLM to infer the user's behavior. 
2. **Synthesize** — observations are grouped by session and synthesized into titled, evidence-backed insights with context on when each pattern applies.
3. **Layer** — insights from multiple sessions are merged into higher-order patterns, revealing cross-session behaviors invisible at the individual session level.
4. **Explore** — navigate the resulting lattice interactively — hover any node to read its full text, trace it back to its supporting observations.

### Lattice structure

| Layer | Contents |
|-------|----------|
| 0 | Raw observations — inferred emotional/cognitive states from interaction windows |
| 1+ | Insights — higher-order inferred motivations that are induced from the layer below|

Edges link each insight back to the observations or lower-level insights that support it.

## Supported providers
Pass different providers per role for cost/quality tradeoffs:

```python
from lattice import AsyncLLM, SyncLLM

model = AsyncLLM(name="claude-opus-4-6", api_key=os.getenv("ANTHROPIC_API_KEY"))
format_model = SyncLLM(name="claude-haiku-4-5", api_key=os.getenv("ANTHROPIC_API_KEY"))
```

## Documentation

Full documentation is available at **[https://stanfordhci.github.io/lattice](https://stanfordhci.github.io/lattice)**.

## Citation

If you use Behavior Latticing in academic work, please cite:

```bibtex
@article{zhao2026behavior,
  title={Behavior Latticing: Inferring User Motivations from Unstructured Interactions},
  author={Zhao, Dora and Lam, Michelle S and Yang, Diyi and Bernstein, Michael S},
  journal={arXiv preprint arXiv:2604.07629},
  year={2026}
}
```

## License

MIT — see [LICENSE](LICENSE) for details.
