runagent

Crates.iorunagent
lib.rsrunagent
version0.1.47
created_at2025-07-11 10:48:27.447574+00
updated_at2025-12-20 19:13:09.328629+00
descriptionRunAgent SDK for Rust - Client SDK for interacting with deployed AI agents
homepagehttps://run-agent.ai
repositoryhttps://github.com/runagent-dev/runagent
max_upload_size
id1747665
size230,101
Radeen Mostafa (RadeenXALNW)

documentation

https://docs.run-agent.ai

README

RunAgent Rust SDK

Crates.io Docs Build Status

Rust bindings for the RunAgent platform. Use it to call agents you deploy with the CLI—whether they run locally on your laptop or remotely on backend.run-agent.ai.


Installation

cargo add runagent tokio serde_json futures
[dependencies]
runagent = "0.1"
tokio = { version = "1.35", features = ["full"] }
serde_json = "1.0"
futures = "0.3"

Configuration Overview

The SDK uses a single constructor pattern. All configuration is done through RunAgentClientConfig:

use runagent::RunAgentClientConfig;

// Local agent with explicit address
let client = RunAgentClient::new(
    RunAgentClientConfig::new("agent-id", "entrypoint")
        .with_local(true)
        .with_address("127.0.0.1", 8450)
        .with_enable_registry(false)
).await?;

// Remote agent
let client = RunAgentClient::new(
    RunAgentClientConfig::new("agent-id", "entrypoint")
        .with_api_key(env::var("RUNAGENT_API_KEY").unwrap())
).await?;

// Remote agent with persistent memory
let client = RunAgentClient::new(
    RunAgentClientConfig::new("agent-id", "entrypoint")
        .with_api_key(env::var("RUNAGENT_API_KEY").unwrap())
        .with_user_id("user123")
        .with_persistent_memory(true)
).await?;
Setting Cloud Local (auto discovery) Local (explicit)
local false (default) true true
Host / Port derived from URL looked up via SQLite with_address()
Base URL RUNAGENT_BASE_URL || default n/a n/a
API Key RUNAGENT_API_KEY (required) optional optional
Registry n/a true (default) false
user_id optional optional optional
persistent_memory optional (false default) optional (false default) optional (false default)
  • RUNAGENT_API_KEY: Bearer token for remote agents (can be set via env var or with_api_key()).
  • RUNAGENT_BASE_URL: Override the default cloud endpoint (e.g. staging).
  • user_id: Optional user identifier for persistent storage across agent executions.
  • persistent_memory: Enable persistent memory to maintain state across multiple agent calls (default: false).
  • For local discovery, install the crate with the db feature and ensure the CLI has registered the agent in ~/.runagent/runagent_local.db.

Usage

Sync (Blocking) - Simplest

Non-streaming

use runagent::blocking::{RunAgentClient, RunAgentClientConfig};
use serde_json::json;

fn main() -> runagent::RunAgentResult<()> {
    // Direct struct construction
    let client = RunAgentClient::new(RunAgentClientConfig {
        agent_id: "agent-id".to_string(),
        entrypoint_tag: "entrypoint".to_string(),
        api_key: Some("your-api-key".to_string()),
        base_url: Some("http://localhost:8333/".to_string()),
        ..RunAgentClientConfig::default() // Omits None values
    })?;

    let response = client.run(&[("message", json!("Hello!"))])?;
    println!("Response: {}", response);
    Ok(())
}

Streaming

use runagent::blocking::{RunAgentClient, RunAgentClientConfig};
use serde_json::json;

fn main() -> runagent::RunAgentResult<()> {
    let client = RunAgentClient::new(RunAgentClientConfig {
        agent_id: "agent-id".to_string(),
        entrypoint_tag: "entrypoint_stream".to_string(),
        api_key: Some("your-api-key".to_string()),
        ..RunAgentClientConfig::default()
    })?;

    // Streaming collects all chunks into a vector
    let chunks = client.run_stream(&[("message", json!("Hello!"))])?;
    for chunk in chunks {
        println!(">> {}", chunk?);
    }
    Ok(())
}

Async (Recommended)

Non-streaming

use runagent::{RunAgentClient, RunAgentClientConfig};
use serde_json::json;

#[tokio::main]
async fn main() -> runagent::RunAgentResult<()> {
    // Direct struct construction
    let client = RunAgentClient::new(RunAgentClientConfig {
        agent_id: "agent-id".to_string(),
        entrypoint_tag: "entrypoint".to_string(),
        api_key: Some("your-api-key".to_string()),
        base_url: Some("http://localhost:8333/".to_string()),
        ..RunAgentClientConfig::default()
    }).await?;

    let response = client.run(&[("message", json!("Hello!"))]).await?;
    println!("Response: {}", response);
    Ok(())
}

Streaming

use runagent::{RunAgentClient, RunAgentClientConfig};
use serde_json::json;
use futures::StreamExt;

#[tokio::main]
async fn main() -> runagent::RunAgentResult<()> {
    let client = RunAgentClient::new(RunAgentClientConfig {
        agent_id: "agent-id".to_string(),
        entrypoint_tag: "entrypoint_stream".to_string(),
        api_key: Some("your-api-key".to_string()),
        ..RunAgentClientConfig::default()
    }).await?;

    // Real streaming - processes chunks as they arrive
    let mut stream = client.run_stream(&[("message", json!("Hello!"))]).await?;
    while let Some(chunk) = stream.next().await {
        println!(">> {}", chunk?);
    }
    Ok(())
}

Alternative: Builder Pattern

You can also use the builder pattern instead of direct struct construction:

use runagent::{RunAgentClient, RunAgentClientConfig};

// Async
let client = RunAgentClient::new(
    RunAgentClientConfig::new("agent-id", "entrypoint")
        .with_api_key("your-api-key")
        .with_base_url("http://localhost:8333/")
).await?;

// Sync
use runagent::blocking::RunAgentClient;
let client = RunAgentClient::new(
    RunAgentClientConfig::new("agent-id", "entrypoint")
        .with_api_key("your-api-key")
        .with_base_url("http://localhost:8333/")
)?;

Local Agents

With explicit address

use runagent::{RunAgentClient, RunAgentClientConfig};

let client = RunAgentClient::new(RunAgentClientConfig {
    agent_id: "local-agent-id".to_string(),
    entrypoint_tag: "minimal".to_string(),
    local: Some(true),
    host: Some("127.0.0.1".to_string()),
    port: Some(8452),
    enable_registry: Some(false), // Skip DB lookup
    ..RunAgentClientConfig::default()
}).await?;

With auto-discovery (requires db feature)

let client = RunAgentClient::new(RunAgentClientConfig {
    agent_id: "local-agent-id".to_string(),
    entrypoint_tag: "minimal".to_string(),
    local: Some(true),
    // enable_registry defaults to true for local agents
    ..RunAgentClientConfig::default()
}).await?;

Guardrails: tags ending with _stream can only be run via run_stream*. Non-stream tags must be run via run*. The client raises clear errors (STREAM_ENTRYPOINT, NON_STREAM_ENTRYPOINT) with suggestions.


Architecture Expectations

During initialization the client calls /api/v1/agents/{id}/architecture and expects the envelope:

{
  "success": true,
  "data": {
    "agent_id": "…",
    "entrypoints": [
      { "tag": "minimal", "file": "main.py", "module": "run", "extractor": {} }
    ]
  },
  "message": "Agent architecture retrieved successfully",
  "error": null,
  "timestamp": "…",
  "request_id": "…"
}
  • If success === false we propagate error.code/message/suggestion/details.
  • If data.entrypoints is missing we raise ARCHITECTURE_MISSING.
  • When an entrypoint can’t be found we log the list returned by the server to help debug typos.

API Reference

Client Creation

Method Description
RunAgentClient::new(config: RunAgentClientConfig) Single constructor for all client types.

Configuration Builder

Method Description
RunAgentClientConfig::new(agent_id, entrypoint_tag) Create config with required fields.
.with_local(bool) Set local flag (default: false).
.with_address(host, port) Set explicit host/port for local agents.
.with_api_key(key) Set API key (overrides env var).
.with_base_url(url) Override default base URL.
.with_enable_registry(bool) Enable/disable database lookup (default: true for local).
.with_user_id(user_id) Set user ID for persistent storage.
.with_persistent_memory(bool) Enable persistent memory across executions (default: false).
.with_extra_params(params) Set extra parameters for future use.

Client Methods

Method Description
run / run_with_args Execute non-streaming entrypoints.
run_stream / run_stream_with_args Execute streaming entrypoints (async stream of Value).
health_check Check if the agent is reachable.
get_agent_architecture Fetch the normalized architecture (see above).

All methods return RunAgentResult<T> where RunAgentError::Execution { code, message, suggestion, details } carries actionable metadata (e.g. AGENT_NOT_FOUND_REMOTE, STREAM_ENTRYPOINT, AUTHENTICATION_ERROR). Inspect these fields to guide users.


Troubleshooting

Symptom Resolution
STREAM_ENTRYPOINT Call run_stream* or switch to a non-stream tag.
NON_STREAM_ENTRYPOINT Call run* or deploy a _stream entrypoint.
AGENT_NOT_FOUND_LOCAL Ensure the agent is registered locally (runagent serve or runagent config --register-agent).
AGENT_NOT_FOUND_REMOTE Verify the agent ID and that your API key has access.
AUTHENTICATION_ERROR Set RUNAGENT_API_KEY env var or use .with_api_key() in config.
ARCHITECTURE_MISSING Redeploy the agent; ensure entrypoints are defined in runagent.config.json.

Security Best Practices

  • Never hardcode API keys; use env vars or secret managers.
  • For browser/edge bridging, proxy calls through your backend rather than exposing long-lived keys.
  • When running locally, restrict access to ~/.runagent/runagent_local.db.

Development & Publishing

cargo fmt
cargo clippy --all-targets --all-features -- -D warnings
cargo test --all-features

To publish a new release, follow ../PUBLISH.md (version bump, cargo package, cargo publish, tag release).


Need Help?

Commit count: 0

cargo fmt