TypeScript SDK
The full SteerPlane guardrail pipeline for Node.js — guard(), the SteerPlane class, and a direct REST client.
The TypeScript SDK mirrors the Python SDK feature-for-feature: the same loop detector, cost tracker, and policy engine, running the same guarantees in a Node.js process.
npm install steerplaneguard() — higher-order function
The TypeScript equivalent of the Python @guard decorator wraps an async function instead of
decorating it.
import { guard } from "steerplane";
const runAgent = guard(
async () => {
await agent.run(); // your code, unchanged
},
{
agentName: "support_bot",
maxCostUsd: 10.0,
maxSteps: 50,
policy: { deniedActions: ["delete_*", "drop_*"] },
enforcement: "alert",
}
);
await runAgent();SteerPlane class — context-manager style
For logging individual steps or nested runs, use the SteerPlane class directly.
import { SteerPlane } from "steerplane";
const sp = new SteerPlane({ agentId: "support_bot" });
await sp.run(
async (run) => {
await run.logStep({ action: "search_web", tokens: 1200, cost: 0.004 });
await run.logStep({ action: "summarize", tokens: 800, cost: 0.002 });
},
{ maxCostUsd: 10, maxSteps: 50 }
);getActiveRun()
Retrieve the currently active run from anywhere in the call stack — useful inside nested helper
functions that don't have direct access to the run object.
import { getActiveRun } from "steerplane";
function helper() {
const run = getActiveRun();
run?.logStep({ action: "helper_call", tokens: 50 });
}Core classes (same guarantees as Python)
| Export | Purpose |
|---|---|
LoopDetector, detectLoop | The same O(W²) sliding-window loop detector. |
CostTracker, DEFAULT_PRICING | Per-session cost accumulation and built-in model pricing. |
PolicyEngine, globMatch | The same deny → allow → rate-limit → approval evaluation order. |
RunManager | Run lifecycle and step logging (used internally by SteerPlane.run). |
import { PolicyEngine } from "steerplane";
const policy = new PolicyEngine({
deniedActions: ["delete_*", "drop_*"],
allowedActions: ["search_*", "read_*"],
// note: RateLimitSpec fields are snake_case, unlike the rest of the TS API
rateLimits: [{ pattern: "send_email", max_count: 5, window_seconds: 60 }],
});
const decision = policy.check("delete_users");
// throws PolicyViolationErrorSteerPlaneClient — direct REST access
For custom integrations that don't fit the guard()/SteerPlane shapes, SteerPlaneClient talks
to the control-plane API directly (the same API the CLI and dashboard use). Its methods take
positional arguments and manage run/step IDs explicitly — guard() and SteerPlane are thin
wrappers around this client that handle those details for you.
import { SteerPlaneClient, generateRunId } from "steerplane";
const client = new SteerPlaneClient(process.env.STEERPLANE_API_URL, process.env.STEERPLANE_API_KEY);
const runId = generateRunId();
await client.startRun(runId, "support_bot", /* maxCostUsd */ 10, /* maxSteps */ 50);
await client.logStep({
runId,
stepNumber: 1,
action: "search_web",
tokens: 1200,
costUsd: 0.004,
});
await client.endRun(runId, "completed", /* totalCost */ 0.004, /* totalSteps */ 1);Errors
The same exception hierarchy as Python — see Exceptions reference for what each one means. In TypeScript they're thrown, not raised:
import { LoopDetectedError, CostLimitExceeded, PolicyViolationError } from "steerplane";
try {
await runAgent();
} catch (err) {
if (err instanceof CostLimitExceeded) {
// handle cost breach
}
}Configuration resolution (env vars → defaults) and the .steerplane.yml file work identically
across both SDKs — see CLI & Configuration.