adk-artifact
Binary artifact storage for Rust Agent Development Kit (ADK-Rust) agents.
Overview
adk-artifact provides versioned binary data storage for the Rust Agent Development Kit (ADK-Rust). Artifacts are useful for storing images, documents, audio, and other binary data that agents produce or consume.
Two storage backends are included:
| Backend | Type | Persistence | Use case |
|---|---|---|---|
InMemoryArtifactService |
In-memory HashMap |
Process lifetime only | Development, testing |
FileArtifactService |
Local filesystem | Durable | Single-node production, local dev |
Both implement the ArtifactService trait, so you can swap backends without changing application code.
Installation
[]
= "0.5.0"
Or via the umbrella crate:
[]
= { = "0.5.0", = ["artifacts"] }
Quick Start
use ;
use Part;
let service = new;
// Save an artifact (version auto-increments from 1)
let resp = service.save.await?;
println!; // 1
// Load the latest version
let resp = service.load.await?;
Storage Backends
InMemoryArtifactService
Stores artifacts in a thread-safe HashMap behind RwLock. Data is lost when the process exits.
use InMemoryArtifactService;
let service = new;
FileArtifactService
Persists artifacts to the local filesystem. Each version is stored as a JSON-serialized file under a directory hierarchy:
<base_dir>/<app_name>/<user_id>/<session_id>/<file_name>/v1.json
v2.json
use FileArtifactService;
let service = new?;
FileArtifactService includes a health_check() method that verifies the base directory is writable.
ArtifactService Trait
All backends implement the full ArtifactService trait:
| Method | Description |
|---|---|
save(SaveRequest) |
Store an artifact. Auto-increments version when version: None. |
load(LoadRequest) |
Retrieve an artifact. Loads latest version when version: None. |
delete(DeleteRequest) |
Delete a specific version, or all versions when version: None. |
list(ListRequest) |
List all artifact filenames in a session (includes user-scoped artifacts). |
versions(VersionsRequest) |
List all available version numbers for a specific artifact. |
health_check() |
Verify backend connectivity. Default impl returns Ok(()). |
Versioning
Every artifact supports multiple versions. When saving with version: None, the version auto-increments starting from 1. You can also write to an explicit version:
// Auto-increment: first save → v1, second save → v2
service.save.await?;
service.save.await?;
// Explicit version
service.save.await?;
// List all versions (returned in descending order)
let resp = service.versions.await?;
// resp.versions == [2, 1]
Scoping
Artifacts are scoped by three dimensions: app_name, user_id, and session_id. This means two sessions for the same user can each have a report.pdf without conflict.
User-Scoped Artifacts
Prefix a filename with user: to make it accessible across all sessions for that user:
// Save from session A
service.save.await?;
// Load from session B — same artifact
service.load.await?;
// list() from any session returns user-scoped artifacts too
let resp = service.list.await?;
// resp.file_names includes "user:profile.png"
Internally, user-scoped artifacts are stored under a shared _user_scoped_ directory (filesystem) or a "user" session key (in-memory), so they're visible regardless of which session ID is used.
Deleting Artifacts
use DeleteRequest;
// Delete a specific version
service.delete.await?;
// Delete all versions
service.delete.await?;
Deleting a non-existent artifact or version is a no-op (no error returned).
ScopedArtifacts
ScopedArtifacts wraps an ArtifactService and implements the simpler adk_core::Artifacts trait by automatically injecting app_name, user_id, and session_id into every request. This is the interface agents use at runtime.
use ;
use ;
use Arc;
let service = new;
let artifacts = new;
// Simple three-method API
let version = artifacts.save.await?;
let loaded = artifacts.load.await?;
let files = artifacts.list.await?;
File Name Validation
Both backends validate artifact filenames to prevent path traversal attacks. The following are rejected with an AdkError::Artifact error:
- Empty names
- Names containing
/or\ - Names equal to
.or.. - Names containing
..anywhere
// These all return Err:
service.save.await; // empty
service.save.await; // traversal
service.save.await; // path separator
Use with LoadArtifactsTool
Artifacts integrate with agents via LoadArtifactsTool from adk-tool:
use LoadArtifactsTool;
let tool = new;
let agent = new
.tool
.build?;
The LLM can then call this tool to load artifacts by name into the conversation.
Related Crates
License
Apache-2.0
Part of ADK-Rust
This crate is part of the ADK-Rust framework for building AI agents in Rust.