These Rust examples are real runnable files. Edit the source file first; this page is rebuilt from the checked-in example and its metadata header.
Rust Grounded Support Agent
Answers a support question grounded in a handbook that is kept out of the model prompt via contextFields.
- Provider:
openai - Env:
OPENAI_API_KEY,OPENAI_APIKEY - Level:
beginner - Run:
npm run example -- rust src/examples/rust/short-agents/basic_agent.rs - Source: src/examples/rust/short-agents/basic_agent.rs
use axllm::runtime::quickjs::QuickJsCodeRuntime;
use axllm::{agent_with_options, AxResult, OpenAICompatibleClient};
use serde_json::json;
use std::env;
fn openai_client() -> AxResult<OpenAICompatibleClient> {
let api_key = env::var("OPENAI_API_KEY")
.or_else(|_| env::var("OPENAI_APIKEY"))
.map_err(|_| {
axllm::AxError::runtime("Set OPENAI_API_KEY or OPENAI_APIKEY to run this example.")
})?;
let model = env::var("AX_OPENAI_MODEL").unwrap_or_else(|_| "gpt-5.4-mini".to_string());
Ok(OpenAICompatibleClient::new(api_key, model).with_model_config(json!({"temperature": 0})))
}
fn main() -> AxResult<()> {
let mut client = openai_client()?;
// The handbook can be arbitrarily large. Listing it in `contextFields` keeps
// it in the agent's runtime so it never inflates the model prompt -- the agent
// reads it through code, not through tokens.
let handbook = r#"
# Acme Cloud -- Support Handbook
## Billing
- Invoices are issued on the 1st of each month and are due net-15.
- Plan downgrades take effect at the END of the current billing cycle, not immediately.
- Refunds are issued to the original payment method within 5 business days.
## Access
- Seats can be added by any workspace Owner under Settings -> Members.
- SSO (SAML) is available on Enterprise; SCIM provisioning is Owner-only.
## Incidents
- Status and uptime are published at status.acme.example.
- Sev-1 incidents page the on-call within 5 minutes; updates post every 30 minutes.
## Data
- Exports are available in CSV and JSON from Settings -> Data.
- Deleted workspaces are recoverable for 30 days, then permanently purged.
"#;
// `with_runtime` attaches the embedded JS engine so the agent loop can run.
let mut assistant = agent_with_options(
"question:string, handbook:string -> answer:string, citations:string[] \"Handbook sections the answer relies on\"",
json!({"contextFields": ["handbook"], "runtime": {"language": "JavaScript"}}),
)?
.with_runtime(Box::new(QuickJsCodeRuntime::new()))?;
let output = assistant.forward_with_options(
&mut client,
json!({
"question": "A customer downgraded their plan today. When does it take effect, and can they get a refund for the current cycle?",
"handbook": handbook,
}),
json!({"max_actor_steps": 12}),
)?;
println!("{}", serde_json::to_string_pretty(&output)?);
Ok(())
}Rust Incident Triage Agent
Triages a noisy incident report held in contextFields, using a lean contextPolicy to keep the raw log out of the prompt while it reasons.
- Provider:
openai - Env:
OPENAI_API_KEY,OPENAI_APIKEY - Level:
intermediate - Run:
npm run example -- rust src/examples/rust/short-agents/tools_agent.rs - Source: src/examples/rust/short-agents/tools_agent.rs
use axllm::runtime::quickjs::QuickJsCodeRuntime;
use axllm::{agent_with_options, AxResult, OpenAICompatibleClient};
use serde_json::json;
use std::env;
fn openai_client() -> AxResult<OpenAICompatibleClient> {
let api_key = env::var("OPENAI_API_KEY")
.or_else(|_| env::var("OPENAI_APIKEY"))
.map_err(|_| {
axllm::AxError::runtime("Set OPENAI_API_KEY or OPENAI_APIKEY to run this example.")
})?;
let model = env::var("AX_OPENAI_MODEL").unwrap_or_else(|_| "gpt-5.4-mini".to_string());
Ok(OpenAICompatibleClient::new(api_key, model).with_model_config(json!({"temperature": 0})))
}
fn main() -> AxResult<()> {
let mut client = openai_client()?;
// A raw, noisy incident report. It lives in `contextFields`, so the agent works
// it inside the runtime; `contextPolicy: lean` keeps the prompt compact by
// preferring live runtime state and summaries over replaying the raw text.
let report = r#"[2026-03-02 14:01:22Z] INFO gateway deploy svc-checkout-edge v812 -> prod (channel: canary 10%)
[2026-03-02 14:03:10Z] WARN checkout-api p95 latency 1180ms (baseline 240ms) region=eu-west-1
[2026-03-02 14:04:55Z] ERROR checkout-api 502 from svc-payments-gw: upstream timeout (10s) tenant_tier=enterprise
[2026-03-02 14:05:01Z] ERROR checkout-api 502 from svc-payments-gw: upstream timeout (10s) tenant_tier=enterprise
[2026-03-02 14:05:40Z] WARN payments-gw circuit half-open, 3 retries exhausted for order=ord_99214
[2026-03-02 14:06:12Z] INFO gateway canary widened 10% -> 50% for svc-checkout-edge v812
[2026-03-02 14:07:33Z] ERROR checkout-api 502 from svc-payments-gw: upstream timeout (10s) tenant_tier=enterprise
[2026-03-02 14:08:02Z] ERROR checkout-api user-visible: "Payment could not be processed" shown to 1,284 sessions
[2026-03-02 14:09:48Z] WARN payments-gw connection pool exhausted (max=64) waiting=210
[2026-03-02 14:11:20Z] INFO on-call paged: SEV-2 opened (eu-west-1 checkout error rate 38%)
[2026-03-02 14:14:05Z] INFO gateway rollback svc-checkout-edge v812 -> v811 (channel: prod 100%)
[2026-03-02 14:17:41Z] INFO checkout-api p95 latency 260ms, error rate 0.4% region=eu-west-1
[2026-03-02 14:19:10Z] INFO on-call SEV-2 mitigated, monitoring for 30m"#;
// `with_runtime` attaches the embedded JS engine so the agent loop can run.
let mut triage = agent_with_options(
"report:string, question:string -> severity:class \"low, medium, high, critical\", rootCause:string, nextSteps:string[], evidence:string[] \"Quoted log lines that support the assessment\"",
json!({
"contextFields": ["report"],
"contextPolicy": {"preset": "lean", "budget": "balanced"},
"runtime": {"language": "JavaScript"},
}),
)?
.with_runtime(Box::new(QuickJsCodeRuntime::new()))?;
let output = triage.forward_with_options(
&mut client,
json!({
"report": report,
"question": "What happened, how bad was it, and what should the on-call do next? Cite the lines you relied on.",
}),
json!({"max_actor_steps": 12}),
)?;
println!("{}", serde_json::to_string_pretty(&output)?);
Ok(())
}Rust Specialist Planner Agent
A specialist that plans a migration from a long brief held in contextFields, using a checkpointed contextPolicy and a runtime-output cap to stay compact.
- Provider:
openai - Env:
OPENAI_API_KEY,OPENAI_APIKEY - Level:
advanced - Run:
npm run example -- rust src/examples/rust/short-agents/handoff_agent.rs - Source: src/examples/rust/short-agents/handoff_agent.rs
use axllm::runtime::quickjs::QuickJsCodeRuntime;
use axllm::{agent_with_options, AxResult, OpenAICompatibleClient};
use serde_json::json;
use std::env;
fn openai_client() -> AxResult<OpenAICompatibleClient> {
let api_key = env::var("OPENAI_API_KEY")
.or_else(|_| env::var("OPENAI_APIKEY"))
.map_err(|_| {
axllm::AxError::runtime("Set OPENAI_API_KEY or OPENAI_APIKEY to run this example.")
})?;
let model = env::var("AX_OPENAI_MODEL").unwrap_or_else(|_| "gpt-5.4-mini".to_string());
Ok(OpenAICompatibleClient::new(api_key, model).with_model_config(json!({"temperature": 0})))
}
fn main() -> AxResult<()> {
let mut client = openai_client()?;
// A long, messy brief -- exactly the kind of input you do not want replayed into
// the prompt on every turn. `contextFields` holds it in the runtime, the
// `checkpointed` policy compacts older turns once the prompt grows, and
// `maxRuntimeChars` caps how much runtime output is echoed back.
let brief = r#"# Migration brief: monolith -> services (draft, unordered notes)
Current: single Rails monolith, Postgres primary + 1 replica, Sidekiq for jobs.
Pain: deploys take 40m, one bad migration locks the orders table, on-call burnout.
Constraints: no downtime windows > 5m, PCI scope must shrink, team of 6, 2 quarters.
Hot paths: checkout (writes orders, payments), search (read-heavy), notifications (async).
Known landmines: payments code has no tests; search shares the orders DB; a nightly
cron rebuilds the catalog and pins CPU for ~20m; the replica lags up to 90s under load.
Org wants: independent deploys for checkout, smaller blast radius, an audit trail.
Nice to have: event log for orders, read-model for search, feature flags.
Hard no: a big-bang rewrite; introducing Kubernetes this year."#;
// `with_runtime` attaches the embedded JS engine so the agent loop can run.
let mut specialist = agent_with_options(
"brief:string, goal:string -> plan:string[] \"Ordered, concrete steps\", answer:string, risks:string[]",
json!({
"contextFields": ["brief"],
"contextPolicy": {"preset": "checkpointed", "budget": "balanced"},
"maxRuntimeChars": 3000,
"runtime": {"language": "JavaScript"},
}),
)?
.with_runtime(Box::new(QuickJsCodeRuntime::new()))?;
let output = specialist.forward_with_options(
&mut client,
json!({
"brief": brief,
"goal": "Propose a safe, incremental 2-quarter plan to split checkout out first, respecting the hard constraints.",
}),
json!({"max_actor_steps": 12}),
)?;
println!("{}", serde_json::to_string_pretty(&output)?);
Ok(())
}Rust Multi-Model Panel
Fans one question across three providers (OpenAI, Gemini, Anthropic), then judges the candidates and synthesizes a single grounded answer.
- Provider:
openai - Env:
OPENAI_API_KEY,OPENAI_APIKEY,GOOGLE_APIKEY,ANTHROPIC_APIKEY - Level:
advanced - Run:
npm run example -- rust src/examples/rust/short-agents/model_panel.rs - Source: src/examples/rust/short-agents/model_panel.rs
use axllm::{ax, AnthropicClient, AxResult, GoogleGeminiClient, OpenAICompatibleClient};
use serde_json::{json, Value};
use std::env;
fn main() -> AxResult<()> {
let openai_key = env::var("OPENAI_API_KEY")
.or_else(|_| env::var("OPENAI_APIKEY"))
.ok();
let google_key = env::var("GOOGLE_APIKEY")
.or_else(|_| env::var("GOOGLE_API_KEY"))
.ok();
let anthropic_key = env::var("ANTHROPIC_APIKEY")
.or_else(|_| env::var("ANTHROPIC_API_KEY"))
.ok();
let (Some(openai_key), Some(google_key), Some(anthropic_key)) =
(openai_key, google_key, anthropic_key)
else {
return Err(axllm::AxError::runtime(
"Set OPENAI_APIKEY, GOOGLE_APIKEY, and ANTHROPIC_APIKEY to run this multi-provider panel.",
));
};
// A panel of three different providers, each answering the same question
// independently. Plain ax() composition (no agent runtime): fan out to the
// panel, judge the candidates, then synthesize one grounded answer.
let mut openai = OpenAICompatibleClient::new(openai_key, "gpt-5.4-mini")
.with_model_config(json!({"temperature": 0}));
let mut gemini =
GoogleGeminiClient::new(google_key, "gemini-3.5-flash").with_profile("google-gemini");
let mut anthropic =
AnthropicClient::new(anthropic_key, "claude-haiku-4-5").with_profile("anthropic");
let mut researcher = ax(
"question:string -> answer:string, keyFindings:string[], citations:string[], confidence:number",
)?;
researcher.set_instruction(
"Answer independently. Use evidence. Call out uncertainty. Do not optimize for consensus.",
);
let mut judge = ax(
"question:string, candidates:json -> consensus:string[], contradictions:string[], uniqueInsights:string[], blindSpots:string[]",
)?;
judge.set_instruction(
"Compare the candidates. Find agreement, conflicts, missing coverage, and unique useful points.",
);
let mut synthesizer = ax(
"question:string, candidates:json, review:json -> answer:string, citations:string[], caveats:string[]",
)?;
synthesizer.set_instruction(
"Write one final answer grounded in the candidates and review. Resolve conflicts explicitly.",
);
let question = "What are the strongest arguments for and against a national carbon tax?";
// Fan the same question across every provider, tagging each candidate with
// the model that produced it.
let mut candidates: Vec<Value> = Vec::new();
let panel: [(&str, &mut OpenAICompatibleClient); 3] = [
("openai/gpt-5.4-mini", &mut openai),
("google/gemini-3.5-flash", &mut gemini),
("anthropic/claude-haiku-4.5", &mut anthropic),
];
for (model, client) in panel {
let mut response = researcher.forward(client, json!({"question": question}))?;
if let Value::Object(map) = &mut response {
map.insert("model".to_string(), json!(model));
}
candidates.push(response);
}
// The judge + synthesizer run on one of the panel clients (OpenAI here).
let candidates = Value::Array(candidates);
let review = judge.forward(
&mut openai,
json!({"question": question, "candidates": candidates}),
)?;
let final_answer = synthesizer.forward(
&mut openai,
json!({"question": question, "candidates": candidates, "review": review}),
)?;
println!("{}", serde_json::to_string_pretty(&final_answer)?);
Ok(())
}