Metadata-Version: 2.4
Name: tex-sdk
Version: 1.1.0
Summary: Tex Python SDK — SuperMemory-compatible memory API
Author: Tex
Requires-Python: >=3.9
Description-Content-Type: text/markdown
Requires-Dist: httpx>=0.24.0
Provides-Extra: http2
Requires-Dist: h2>=4.1.0; extra == "http2"
Provides-Extra: test
Requires-Dist: respx>=0.20.0; extra == "test"
Requires-Dist: pytest>=7.0; extra == "test"

# Tex Python SDK

SuperMemory-compatible memory SDK for Python.

## Installation

```bash
pip install tex-sdk
```

Optional HTTP/2 support:

```bash
pip install "tex-sdk[http2]"
```

Requires Python 3.9+.

## Quick Start

### API key

```python
from tex import Tex

client = Tex(api_key="sk-...", base_url="http://localhost:8000")

client.add("The quick brown fox jumps over the lazy dog.")
results = client.search.documents("fox")
```

### Environment variables

Set `TEX_API_KEY` and `TEX_BASE_URL`, then:

```python
from tex import Tex

client = Tex()
```

### Org + user login

```python
from tex import Tex

client = Tex(base_url="http://localhost:8000", org_id="org1", user_id="user1")
```

## Documents

Add, retrieve, update, delete, list, and batch-manage documents.

```python
# Top-level shortcut
resp = client.add("Document content", container_tag="notes")

# Equivalent resource call
resp = client.documents.add("Document content", container_tag="notes")

# Get by ID
doc = client.documents.get("doc_abc123")

# Update
client.documents.update("doc_abc123", content="Updated content")

# Delete
client.documents.delete("doc_abc123")

# List with filters
docs = client.documents.list(container_tags=["notes"], limit=20)

# Batch add
client.documents.batch_add(
    ["First document", "Second document"],
    container_tag="batch-import",
)

# Bulk delete
client.documents.delete_bulk(container_tags=["old-tag"])
```

## Search

### Document search

```python
results = client.search.documents("quarterly revenue", limit=10)

# Alias
results = client.search.execute("quarterly revenue", limit=10)
```

### Memory search

```python
results = client.search.memories("user preferences", container_tag="user1")
```

## Memories

```python
# Add memories
client.memories.add(
    [{"content": "User prefers dark mode"}],
    container_tag="prefs",
)

# Forget a memory
client.memories.forget("prefs", id="mem_abc123")

# Update a memory
client.memories.update_memory("prefs", "User prefers light mode", id="mem_abc123")
```

## Profile

```python
profile = client.profile("user-container-tag")
print(profile.profile)
```

## Tex-Unique Features

### NLQ (Natural Language Query)

```python
result = client.nlq.execute("What meetings did I have last week?")
print(result.text)
print(result.evidence)
```

### Episodes

```python
# Store a conversation
client.episodes.store(
    [
        {"role": "user", "content": "Book a table for two"},
        {"role": "assistant", "content": "Which restaurant?"},
    ],
    episode_id="ep_001",
)

# List episodes
episodes = client.episodes.list(limit=10)
```

### Preferences

```python
client.preferences.store([
    {"key": "drink", "value": "espresso", "confidence": 0.9},
])
```

### DB

```python
result = client.db.query("MATCH (n) RETURN n LIMIT $limit", params={"limit": 5})
schema = client.db.schema()
```

### Auth

```python
info = client.auth.whoami()
```

### Jobs

```python
status = client.jobs.get("job_abc123")
```

## Error Handling

The SDK provides a detailed error hierarchy:

```
TexError
  APIError
    APIConnectionError
      APITimeoutError
    APIStatusError
      BadRequestError          (400)
      AuthenticationError      (401)
      PermissionDeniedError    (403)
      NotFoundError            (404)
      ConflictError            (409)
      UnprocessableEntityError (422)
      RateLimitError           (429)
      InternalServerError      (500+)
    APIResponseValidationError
```

```python
from tex import Tex, NotFoundError, AuthenticationError, APIStatusError

client = Tex(api_key="sk-...", base_url="http://localhost:8000")

try:
    doc = client.documents.get("nonexistent")
except NotFoundError as e:
    print(f"Not found: {e}")
except AuthenticationError as e:
    print(f"Auth failed: {e}")
except APIStatusError as e:
    print(f"HTTP {e.status_code}: {e.message}")
    print(f"Request ID: {e.request_id}")
```

## Configuration

Use `TexConfig` and `TexEndpoints` for advanced configuration:

```python
from tex import Tex, TexConfig, TexEndpoints

config = TexConfig(
    base_url="https://api.example.com",
    api_key="sk-...",
    timeout_s=30.0,
    max_retries=3,
    http2=True,
    endpoints=TexEndpoints(
        db_query="/custom/db/query",
        db_schema="/custom/db/schema",
    ),
)

client = Tex(config=config)
```

Default timeout is 60 seconds. Default max retries is 2.

## Migration from SuperMemory

| SuperMemory | Tex SDK |
|---|---|
| `client.add(content)` | `client.add(content)` or `client.documents.add(content)` |
| `client.documents.get(id)` | `client.documents.get(id)` |
| `client.documents.update(id)` | `client.documents.update(id)` |
| `client.documents.delete(id)` | `client.documents.delete(id)` |
| `client.documents.list()` | `client.documents.list()` |
| `client.documents.batch_add(docs)` | `client.documents.batch_add(docs)` |
| `client.search.execute(q)` | `client.search.execute(q)` or `client.search.documents(q)` |
| `client.search.memories(q)` | `client.search.memories(q)` |
| `client.memories.add(memories)` | `client.memories.add(memories)` |
| `client.memories.forget(tag)` | `client.memories.forget(tag)` |
| `client.profile(tag)` | `client.profile(tag)` |

Tex extends SuperMemory with additional resources: `nlq`, `episodes`, `preferences`, `db`, `auth`, and `jobs`.

## HTTP/2

HTTP/2 is enabled by default. If the `h2` package is not installed, the SDK falls back to HTTP/1.1 automatically. To install with HTTP/2 support:

```bash
pip install "tex-sdk[http2]"
```

To explicitly disable HTTP/2:

```python
client = Tex(api_key="sk-...", base_url="http://localhost:8000", http2=False)
```
