# velixar
Governed, auditable memory for AI agents — the official Rust client.
```toml
[dependencies]
velixar = "0.1"
tokio = { version = "1", features = ["macros", "rt-multi-thread"] }
```
```rust
use velixar::{Velixar, StoreOpts, SearchOpts};
#[tokio::main]
async fn main() -> velixar::Result<()> {
let client = Velixar::new(std::env::var("VELIXAR_API_KEY").unwrap())?;
client.store(
"Alex is a vegetarian and is allergic to nuts.",
StoreOpts::new().user("alex").tags(["diet", "allergy"]),
).await?;
let hits = client.search(
"what can I cook for dinner?",
SearchOpts::new().user("alex"),
).await?;
for m in hits.memories {
println!("{} ({:.2})", m.content, m.score.unwrap_or_default());
}
Ok(())
}
```
Get a free key at [velixarai.com](https://velixarai.com).
## One key, many users
Your key belongs to your workspace. `.user("alex")` scopes a memory to one of *your*
end users, and a search scoped to Alex never returns another user's memories —
enforced server-side.
## Scopes
Keys carry scopes. `memory:read` and `memory:write` are granted by default.
`delete` requires `memory:delete`, which is opt-in because it is irreversible:
```rust
match client.delete(&id).await {
Err(velixar::Error::Scope(e)) => eprintln!("key needs memory:delete ({})", e.code),
Err(e) => return Err(e),
Ok(_) => {}
}
```
Errors are typed by what you'd *do* about them — `Auth`, `Scope`, `Validation`,
`NotFound`, `RateLimited` — rather than forcing you to string-match on a code.
## Verified against the live API
`cargo test` pins the wire contract; `cargo run --example live` runs the whole flow
against production, including asserting that a scoped search contains no other
user's memories.
MIT licensed.