dexcost 0.2.0

Agent Unit Economics SDK for Rust — track end-to-end business-task costs for AI agents.
Documentation

dexcost

Rust SDK for dexcost -- Agent Unit Economics platform. Track LLM costs, non-LLM service fees, and retry waste attributed to customers, projects, and workflows.

Installation

cargo add dexcost

Or add to your Cargo.toml:

[dependencies]
dexcost = "0.1"

Quickstart

use dexcost::{Config, TaskOptions, TaskStatus, init, start_task, flush, close};
use rust_decimal_macros::dec;

#[tokio::main]
async fn main() {
    // Initialize (local-only mode, no API key needed).
    init(Config::default()).unwrap();

    // Start a task.
    let mut task = start_task("resolve_ticket", TaskOptions {
        customer_id: Some("acme-corp".into()),
        project_id: Some("support".into()),
        ..Default::default()
    }).await.unwrap();

    // Record an LLM call (auto-priced from bundled model data).
    task.record_llm_call("openai", "gpt-4o", 1000, 500, None, None, None)
        .await
        .unwrap();

    // Record a non-LLM cost.
    task.record_cost("google_maps", dec!(0.005), None, None).await.unwrap();

    // Mark a retry.
    task.mark_retry("rate_limit", dec!(0.0)).await.unwrap();

    // End the task.
    task.end(TaskStatus::Success).await.unwrap();

    println!("Total cost: {} USD", task.task().total_cost_usd);

    flush().await.unwrap();
    close();
}

Cloud Mode

To push events to the dexcost Control Layer:

use dexcost::{Config, init};

init(Config {
    api_key: Some("dx_live_your_key_here".into()), // or set DEXCOST_API_KEY env var
    ..Config::default()
}).unwrap();

Events are buffered in memory and pushed in batches every 5 seconds.

Features

  • LLM Cost Tracking -- Record costs for any LLM provider with auto-pricing from bundled model data
  • Non-LLM Cost Tracking -- Track external service costs (APIs, compute, storage)
  • Retry Waste Detection -- First-class retry tracking with is_retry, retry_reason, retry_of
  • Customer Attribution -- Attribute costs to customers, projects, and workflows
  • A/B Testing -- Tag tasks with experiment_id and variant for cost comparison
  • Nested Tasks -- Link parent/child tasks via task-local context
  • Auto-Pricing -- Bundled pricing data for 1000+ LLM models (LiteLLM cost map)
  • Custom Pricing -- Override bundled rates or register custom per-1k-token pricing
  • Background Sync -- Events buffered in memory and pushed to control layer in batches
  • Axum Middleware -- Optional middleware for automatic HTTP request tracking (enable axum-middleware feature)

Custom Pricing

Override bundled LLM pricing:

use dexcost::pricing_engine;
use rust_decimal_macros::dec;

let engine = pricing_engine().unwrap();
let mut engine = engine.lock().await;
engine.set_custom_pricing("my-model", dec!(0.001), dec!(0.002));

Axum Middleware

Enable the axum-middleware feature in Cargo.toml:

[dependencies]
dexcost = { version = "0.1", features = ["axum-middleware"] }

Then add the middleware to your Axum router:

use axum::{Router, middleware};
use dexcost::middleware::axum::dexcost_middleware;

let app = Router::new()
    .layer(middleware::from_fn(move |req, next| {
        dexcost_middleware(req, next, buffer.clone(), None)
    }));

Key Design Decisions

  • All costs use rust_decimal::Decimal -- never f64 for money
  • Costs serialized as strings in JSON output for precision
  • UUIDs generated via uuid::Uuid::v4()
  • Retry waste is a first-class metric (is_retry, retry_reason, retry_of)
  • Schema v1 compatible with the Python, TypeScript, and Go SDKs
  • Thread-safe: Arc<Mutex<>> for shared state

Testing

cargo test

Privacy

When you connect to the Dexcost Control Layer, the SDK transmits usage data subject to our Privacy Policy.

License

MIT — see LICENSE.