erebyx-sdk 0.1.1

Rust SDK for EREBYX — persistent AI memory across every AI you use. Encrypted in transit (TLS 1.3) and at rest with envelope encryption (server-held master KEK at v0.1.1); per-user zero-knowledge encryption in v0.2.
Documentation
# erebyx-sdk

> Type-safe Rust SDK for the EREBYX memory substrate. Persistent AI memory across every AI you use.

[![License: MIT OR Apache-2.0](https://img.shields.io/badge/license-MIT_OR_Apache--2.0-blue.svg)](LICENSE-MIT)
[![Version](https://img.shields.io/badge/version-0.1.1-green.svg)](CHANGELOG.md)
[![Crates.io](https://img.shields.io/badge/crates.io-erebyx--sdk-orange.svg)](https://crates.io/crates/erebyx-sdk)
[![docs.rs](https://img.shields.io/badge/docs.rs-erebyx--sdk-blue.svg)](https://docs.rs/erebyx-sdk)

---

## Install in 5 lines

```toml
# Cargo.toml
[dependencies]
erebyx-sdk = "0.1"
tokio = { version = "1", features = ["macros", "rt-multi-thread"] }
```

```rust
# tokio_test::block_on(async {
let memory = erebyx_sdk::Memory::from_env()?;
let response = memory
    .save("Anchor retrieval improves recall by 40%", "insight")
    .send()
    .await?;
println!("saved {}", response.memory_id);
# Ok::<_, erebyx_sdk::Error>(()) }).unwrap();
```

That's the whole loop: install -> save. Memory is encrypted in transit (TLS 1.3) and at rest using XChaCha20-Poly1305 envelope encryption (AES-256-GCM legacy supported on existing rows) with per-tenant Key Encryption Keys wrapped under a server-held master KEK. Per-user zero-knowledge encryption (passphrase-derived keys, EREBYX cannot decrypt) ships in v0.2.

---

## What it is

`erebyx-sdk` is the Rust client for the EREBYX memory substrate. It exposes the v0.1.1 cognitive surface as five async methods, each returning a builder for optional fields:

| Method | Purpose |
|---|---|
| `restore_identity()` | Wake up — load identity at session start |
| `load_context()` | Resume — load handoff + recent work |
| `save(content, category)` | Store a memory worth keeping |
| `search(query)` | Find what you know by meaning (the `remember` verb) |
| `wrap_up(what_we_built, whats_next)` | Create a session handoff at the end |

All processing — memory understanding, recall, organization, encryption — lives behind the API — you never need to think about it.

---

## Quickstart

```rust
use erebyx_sdk::Memory;

#[tokio::main]
async fn main() -> Result<(), Box<dyn std::error::Error>> {
    // Reads EREBYX_API_KEY + EREBYX_API_URL + EREBYX_INSTANCE_ID from env
    let memory = Memory::from_env()?;

    // Save
    memory.save("Anchor-based retrieval improves recall by 40%", "insight")
        .anchors(vec!["memory", "retrieval"])
        .importance(0.9)
        .send()
        .await?;

    // Search
    let results = memory.search("anchor retrieval performance")
        .limit(5)
        .send()
        .await?;

    for record in &results.memories {
        println!("{}: {}", record.id, record.content);
    }

    // Session handoff
    memory.wrap_up("Wired the SDK into our agent loop", "Add streaming search")
        .anchors(vec!["sdk", "rust"])
        .send()
        .await?;

    Ok(())
}
```

---

## Configuration

```bash
# Required
export EREBYX_API_KEY="<YOUR_API_KEY>"

# Required for tenants registered at v0.1.1+ (Argon2id-default-on).
# Find it in your dashboard recovery panel. At v0.1.1, EREBYX holds a
# server-side master KEK and can decrypt for support/backup/recovery —
# this is NOT zero-knowledge. When per-user zero-knowledge ships in v0.2,
# your passphrase + BIP39 recovery seed become the ONLY keys to your
# memory; losing both will be unrecoverable by design. Keep both safe.
export EREBYX_PASSPHRASE="<YOUR_PASSPHRASE>"

# Optional (defaults shown)
export EREBYX_API_URL="https://core.erebyx.com"
export EREBYX_INSTANCE_ID="default"
```

Get your API key at [app.erebyx.com/keys](https://app.erebyx.com/keys).
The dashboard surfaces the matching `EREBYX_PASSPHRASE` value at registration;
both are required for new tenants.

Or pass everything explicitly:

```rust
let memory = Memory::builder("<YOUR_API_KEY>")
    .api_url("https://core.erebyx.com")
    .instance_id("my-service")
    .build()?;
```

---

## X-Erebyx-Hint — lifecycle signals for free

Every SDK call surfaces the substrate's lifecycle hints (carried on the
`X-Erebyx-Hint` response header) and any tools the substrate auto-fired
(`X-Erebyx-Auto-Fired`). Both are typed fields on every response struct:

```rust
let response = memory.save("...", "insight").send().await?;

for hint in &response.hints {
    match hint.as_str() {
        "wrap_up_recommended" => { /* call wrap_up at next natural break */ }
        "restore_identity_recommended" => { /* identity drift; re-anchor */ }
        "load_context_recommended" => { /* refresh working memory */ }
        "compact_imminent" => { /* consolidate before context fills */ }
        _ => {}
    }
}

// First call against a fresh (instance_id, session_id) tuple typically
// reports `["restore_identity", "load_context"]`; empty thereafter.
println!("auto-fired this call: {:?}", response.auto_fired);
```

Hint values:
- `wrap_up_recommended` — substrate sees a natural consolidation boundary
- `restore_identity_recommended` — voice drift detected
- `load_context_recommended` — retrieval scores trending low
- `compact_imminent` — sustained save volume; consolidate before context fills

Honoring hints is optional — the SDK never acts on them automatically. Full hint protocol at [DEV_QUICKSTART.md](DEV_QUICKSTART.md#x-erebyx-hint--lifecycle-signals).

---

## Reliability

Built-in circuit breaker — after 3 consecutive failures, the SDK refuses calls for 30s, then attempts a half-open retry. Memory failures degrade gracefully and never crash your application.

```rust
match memory.save("...", "insight").send().await {
    Ok(response) => { /* memory persisted */ }
    Err(erebyx_sdk::Error::CircuitOpen { cooldown_secs }) => {
        // Substrate degraded; backed off. Don't block the user;
        // the SDK auto-retries after the cooldown window.
        tracing::warn!(cooldown_secs, "erebyx circuit open; skipping save");
    }
    Err(erebyx_sdk::Error::AuthenticationFailed(msg)) => {
        // Caller-side problem — the API key is wrong / expired.
        // No amount of retry fixes this.
        tracing::error!(?msg, "erebyx auth failed");
    }
    Err(e) => { /* hard error; bubble up */ }
}
```

The SDK emits `tracing::debug!` + `tracing::warn!` events at substrate-call boundaries (circuit-breaker state transitions, retryable failures). Subscribe via `tracing_subscriber` to route them into your observability stack. Per-method spans via `#[instrument]` ship in v0.1.2.

---

## Architecture

```
src/
  lib.rs          Public API (Memory + builders)
  client.rs       HTTP client (reqwest, rustls) + circuit breaker
  middleware.rs   LLM call middleware (before/after memory hooks)
  types.rs        Request / response types
  error.rs        Typed errors
```

The SDK calls the substrate HTTP API at `${EREBYX_API_URL}` using plain JSON. Each method maps to one substrate route (`/v0/memory/store`, `/v0/memory/remember`, `/v0/session/wrap-up`, `/v0/identity/restore`, `/v0/session/load`). Headers on every request: `Authorization: Bearer <api_key>`, `X-Instance-ID`, `X-Erebyx-Session-Id`, `Content-Type: application/json`. Tenants registered at v0.1.1+ also send `X-Passphrase` (read from `EREBYX_PASSPHRASE` env var or `MemoryBuilder::passphrase`).

Override the per-process session id via `MemoryBuilder::session_id` if you want to bind it to an external identifier (harness conversation id, LLM thread id, browser tab id). Defaults to a fresh UUID v4 per builder.

---

## How to upgrade

Track releases in [CHANGELOG.md](CHANGELOG.md). Backward compatibility is a hard guarantee within v0.1.x — every release lists explicit breaking changes (none expected before v0.2).

```toml
[dependencies]
erebyx-sdk = "0.1"   # always picks the latest 0.1.x
```

```bash
cargo update -p erebyx-sdk
```

---

## Build from source

```bash
git clone https://github.com/ProjectErebyx/erebyx-sdk.git
cd erebyx-sdk
cargo build --release
cargo test
```

Requires Rust 1.75+.

---

## See also

- [`erebyx-cli`]https://github.com/ProjectErebyx/erebyx-cli — Native CLI for MCP integration
- [`@erebyx/sdk`]https://github.com/ProjectErebyx/erebyx-sdk-node — Node.js / TypeScript SDK (napi wrapper around this crate)
- [Substrate overview]https://erebyx.com/core — integration patterns + per-harness examples

---

## Contributing

Pull requests welcome. DCO sign-off required (`git commit -s`). See [CONTRIBUTING.md](CONTRIBUTING.md).

## Security

Vulnerability reports → `legal@erebyx.com`. See [SECURITY.md](SECURITY.md).

## License

Dual-licensed under MIT or Apache-2.0 at your option. See
[LICENSE-MIT](LICENSE-MIT), [LICENSE-APACHE-2.0](LICENSE-APACHE-2.0),
and [NOTICE](NOTICE).

---

**Built by EREBYX, LLC** — `https://erebyx.com`