Implements the sentryagent-idp Rust SDK crate (sdk-rust/) with: - TokenManager with Arc<Mutex<TokenCache>> for thread-safe token caching - AgentIdPClient with full method coverage: agents, oauth2, credentials, audit, marketplace, delegation - Error hierarchy via thiserror (AgentIdPError enum) - All model types with serde derive - 429 RateLimited handling with Retry-After parsing; zero unwrap() calls - Unit tests (mockito), doc tests, and integration tests (#[ignore]) - quickstart example, full README, cargo doc clean Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
89 lines
3.9 KiB
Rust
89 lines
3.9 KiB
Rust
//! Quickstart example — register an agent, issue a token, then look it up.
|
|
//!
|
|
//! Run with:
|
|
//! ```bash
|
|
//! AGENTIDP_API_URL=https://api.sentryagent.ai \
|
|
//! AGENTIDP_CLIENT_ID=your-client-id \
|
|
//! AGENTIDP_CLIENT_SECRET=your-client-secret \
|
|
//! cargo run --example quickstart
|
|
//! ```
|
|
|
|
use sentryagent_idp::{AgentIdPClient, AuditLogFilters, MarketplaceFilters, RegisterAgentRequest};
|
|
|
|
#[tokio::main]
|
|
async fn main() -> Result<(), Box<dyn std::error::Error>> {
|
|
// Build client from environment variables.
|
|
let client = AgentIdPClient::from_env()?;
|
|
|
|
// ── Register a new agent ──────────────────────────────────────────────────
|
|
println!("Registering agent...");
|
|
let agent = client
|
|
.register_agent(RegisterAgentRequest {
|
|
name: "quickstart-agent".to_owned(),
|
|
description: Some("Created by the quickstart example".to_owned()),
|
|
agent_type: "worker".to_owned(),
|
|
capabilities: vec!["read:data".to_owned(), "write:reports".to_owned()],
|
|
metadata: None,
|
|
})
|
|
.await?;
|
|
|
|
println!("Registered agent:");
|
|
println!(" ID: {}", agent.id);
|
|
println!(" DID: {}", agent.did);
|
|
|
|
// ── Issue a scoped token ──────────────────────────────────────────────────
|
|
println!("\nIssuing token...");
|
|
let token_resp = client
|
|
.issue_token(&agent.id, &["agents:read", "agents:write"])
|
|
.await?;
|
|
|
|
println!("Token issued:");
|
|
println!(" type: {}", token_resp.token_type);
|
|
println!(" expires_in: {}s", token_resp.expires_in);
|
|
println!(" scope: {}", token_resp.scope);
|
|
|
|
// ── Retrieve the agent by ID ──────────────────────────────────────────────
|
|
println!("\nFetching agent {}...", agent.id);
|
|
let fetched = client.get_agent(&agent.id).await?;
|
|
println!("Fetched: {} (public: {})", fetched.name, fetched.is_public);
|
|
|
|
// ── List agents ───────────────────────────────────────────────────────────
|
|
println!("\nListing agents (page 1)...");
|
|
let list = client.list_agents(Some(1), Some(10)).await?;
|
|
println!("Total agents: {}", list.total);
|
|
|
|
// ── Audit logs ────────────────────────────────────────────────────────────
|
|
println!("\nFetching audit logs...");
|
|
let logs = client
|
|
.list_audit_logs(AuditLogFilters {
|
|
agent_id: Some(agent.id.clone()),
|
|
event_type: None,
|
|
from: None,
|
|
to: None,
|
|
page: 1,
|
|
per_page: 10,
|
|
})
|
|
.await?;
|
|
println!("Audit events: {}", logs.total);
|
|
|
|
// ── Marketplace ───────────────────────────────────────────────────────────
|
|
println!("\nBrowsing marketplace...");
|
|
let marketplace = client
|
|
.list_public_agents(MarketplaceFilters {
|
|
q: None,
|
|
capability: None,
|
|
publisher: None,
|
|
page: 1,
|
|
per_page: 5,
|
|
})
|
|
.await?;
|
|
println!("Public agents: {}", marketplace.total);
|
|
|
|
// ── Clean up ──────────────────────────────────────────────────────────────
|
|
println!("\nDeleting agent {}...", agent.id);
|
|
client.delete_agent(&agent.id).await?;
|
|
println!("Agent deleted. Done.");
|
|
|
|
Ok(())
|
|
}
|