| Crates.io | seasoning |
| lib.rs | seasoning |
| version | 0.1.2 |
| created_at | 2026-01-11 08:39:38.972669+00 |
| updated_at | 2026-01-11 22:05:50.316505+00 |
| description | Embedding and reranking infrastructure with rate limiting and retry logic |
| homepage | |
| repository | https://github.com/casualjim/seasoning |
| max_upload_size | |
| id | 2035417 |
| size | 149,066 |
Embedding + reranking infrastructure as a Rust library.
This repo is not published to crates.io. Use a path dependency:
[dependencies]
seasoning = { path = "." }
use std::time::Duration;
use secrecy::SecretString;
use seasoning::embedding::{
Client as EmbedClient, EmbedderConfig, EmbeddingInput, ProviderDialect,
};
#[tokio::main]
async fn main() -> seasoning::Result<()> {
let embedder = EmbedClient::new(EmbedderConfig {
api_key: Some(SecretString::from("YOUR_API_KEY")),
base_url: "https://api.deepinfra.com/v1/openai".to_string(),
timeout: Duration::from_secs(10),
dialect: ProviderDialect::DeepInfra,
model: "Qwen/Qwen3-Embedding-0.6B".to_string(),
embedding_dim: 1024,
requests_per_minute: 1000,
max_concurrent_requests: 50,
tokens_per_minute: 1_000_000,
})?;
let inputs = vec![
EmbeddingInput {
text: "hello world".to_string(),
token_count: 2,
},
EmbeddingInput {
text: "another string".to_string(),
token_count: 2,
},
];
let result = embedder.embed(&inputs).await?;
println!("got {} embeddings", result.embeddings.len());
Ok(())
}
Notes:
token_count is required per input so the rate limiter can budget tokens.requests_per_minute, max_concurrent_requests, and tokens_per_minute
control the rate limiter and concurrency.use std::time::Duration;
use secrecy::SecretString;
use seasoning::embedding::ProviderDialect;
use seasoning::reranker::{Client as RerankerClient, RerankerConfig};
use seasoning::RerankingProvider;
#[tokio::main]
async fn main() -> seasoning::Result<()> {
let reranker = RerankerClient::new(RerankerConfig {
api_key: Some(SecretString::from("YOUR_API_KEY")),
base_url: "https://api.deepinfra.com/v1".to_string(),
timeout: Duration::from_secs(10),
dialect: ProviderDialect::DeepInfra,
model: "Qwen/Qwen3-Reranker-0.6B".to_string(),
instruction: None,
requests_per_minute: 1000,
max_concurrent_requests: 50,
tokens_per_minute: 1_000_000,
})?;
let query = seasoning::RerankQuery {
text: "search query".to_string(),
token_count: 2,
};
let docs = vec![
seasoning::RerankDocument {
text: "first doc".to_string(),
token_count: 2,
},
seasoning::RerankDocument {
text: "second doc".to_string(),
token_count: 2,
},
seasoning::RerankDocument {
text: "third doc".to_string(),
token_count: 2,
},
];
let scores = reranker.rerank(&query, &docs).await?;
println!("{scores:?}");
Ok(())
}
Notes:
{base_url}/inference/{model}.ProviderDialect::DeepInfra only.seasoning::embedding for embeddingsseasoning::reranker for rerankingseasoning::reqwestx for the rate-limited API clientseasoning::config for config structs (no I/O)