AxioRankDocs

Agent Runs (traces, sessions, metadata)

Group an agent's tool calls and model turns into one run, group runs into sessions, tag calls with your own metadata, and read it all back with per-step cost and latency.

A run is one correlated agent execution: every governed call that shares a traceId, ordered by step. The Agent Runs page (/runs in the console) shows one row per run with its step count, decision mix (allowed, denied, held), total cost and tokens, the models used, duration, and p95 step latency. Open a run to walk the timeline: each step carries its decision, risk signals, redacted payload, latency, cost, and your metadata tags.

Runs are also the unit of multi-step attack detection: kill chains and cross-agent taint lineage render on the same timeline. The security spine and the observability surface read the same governed rows.

Runs, sessions, and kill-chain detection are available on every plan. The telemetry columns (per-run and per-step cost, tokens, models, latency) need the Observability capability (Pro and up).

Start a run

Prefer the trace handle: it generates the id, auto-increments stepIndex, and rides along through every framework adapter.

const t = axio.trace({
  intent: "Refund order #4821",           // shown as the run's label
  sessionId: conversationId,               // groups this run with its siblings
  metadata: { env: "prod", feature: "refunds" },
});

await t.enforce({ tool: "stripe.refund", arguments: { order } }); // step 0
await t.toolCall({ tool: "email.send", arguments: { to } });      // step 1
with axio.trace(
    intent="Refund order #4821",
    session_id=conversation_id,
    metadata={"env": "prod", "feature": "refunds"},
) as t:
    t.enforce("stripe.refund", {"order": order})   # step 0
    t.tool_call("email.send", {"to": to})          # step 1

Every field is optional and degrades safely: a malformed sessionId or an oversized metadata map is dropped by the gateway rather than failing the call.

Stitch model calls into the run

Calls through the AI Gateway join a run via three request headers:

HeaderValue
X-AxioRank-Trace-IdThe run's trace id (uuid).
X-AxioRank-Session-IdOptional session id (uuid).
X-AxioRank-Step-IndexOptional 0 to 100000. Omit to order by time.
X-AxioRank-Parent-Step-IndexOptional. Nests the turn under a spawning step (sub-agents).

The trace handle emits them for you, so an OpenAI-compatible client pointed at the proxy stitches its LLM turns into the same timeline as the tool calls:

const openai = new OpenAI({
  baseURL: "https://www.axiorank.com/api/proxy/v1",
  defaultHeaders: { "X-AxioRank-Key": process.env.AXIORANK_KEY, ...t.headers() },
});
openai = OpenAI(
    base_url="https://www.axiorank.com/api/proxy/v1",
    default_headers={"X-AxioRank-Key": key, **t.headers},
)

With model-I/O governance on (Settings → Governance), proxied turns appear as fully governed steps (decision, risk, redacted content). With it off, a turn that carries a trace header still appears as an observation step: allow, risk 0, with the model, tokens, cost, and latency, but no content stored and no policy evaluated. Send no trace header and the proxy writes no step at all.

Sub-agents

When your agent spawns a sub-agent, create a child handle: its calls share the run's trace id and step numbering but nest under the spawning step on the timeline. The parent defaults to the step the handle issued most recently (usually the spawn call); pass parentStepIndex to pin a different one.

await t.enforce({ tool: "agents.spawn_researcher" }); // step 2
const sub = t.child({ metadata: { role: "researcher" } });
await sub.enforce({ tool: "web.search", arguments: { q } }); // step 3, nested
t.enforce("agents.spawn_researcher")          # step 2
sub = t.child(metadata={"role": "researcher"})
sub.enforce("web.search", {"q": q})           # step 3, nested

sub.headers() (TypeScript) / sub.headers (Python) include X-AxioRank-Parent-Step-Index, so a sub-agent's model calls through the AI Gateway nest the same way.

Sessions

A session groups the runs of one conversation: pass the same sessionId (any uuid you mint) across traces and the runs list filters by it (/runs?session=<uuid>). Set it per trace, or once on the client:

const axio = new AxioRank({ apiKey, sessionId: conversationId });

Metadata

metadata is a small tag map surfaced on the run timeline: at most 16 keys, keys up to 64 characters, string values up to 256 characters, 2KB serialized. Values pass the same write-time masking as payloads, so a secret pasted into a tag is redacted before storage. Do not put secrets or personal data in metadata; treat it as labels (environment, feature, your own request id), not payload.

Handle-level metadata rides on every call made through the trace; a per-call metadata wins on key conflicts.

Reading runs back

  • Console: /runs (list, filter by agent, session, kill chain) and /runs/<traceId> (timeline).
  • OTLP export: each step exports as a span carrying axiorank.session_id alongside the decision, risk, and taint attributes. See SIEM and OTLP export.
  • API: audit-log export includes trace_id, session_id, and client_metadata columns.

Correlation fields (traceId, stepIndex, sessionId, metadata) live outside the sealed row hash, so they never affect audit-ledger verification. The steps themselves remain tamper-evident and offline-verifiable.

On this page