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 Version Crates.io docs.rs


Install in 5 lines

# Cargo.toml
[dependencies]
erebyx-sdk = "0.1"
tokio = { version = "1", features = ["macros", "rt-multi-thread"] }
# 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

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

# 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. The dashboard surfaces the matching EREBYX_PASSPHRASE value at registration; both are required for new tenants.

Or pass everything explicitly:

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:

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.


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.

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. Backward compatibility is a hard guarantee within v0.1.x — every release lists explicit breaking changes (none expected before v0.2).

[dependencies]
erebyx-sdk = "0.1"   # always picks the latest 0.1.x
cargo update -p erebyx-sdk

Build from source

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

Requires Rust 1.75+.


See also


Contributing

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

Security

Vulnerability reports → legal@erebyx.com. See SECURITY.md.

License

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


Built by EREBYX, LLChttps://erebyx.com