Async decorator — protect_async
Use protect_async for FastAPI, asyncio, and other async frameworks with contextvars support.
Async decorator
For async agent frameworks (FastAPI, asyncio, aioboto3), use protect_async instead of protect. It uses contextvars.ContextVar instead of threading.local(), making last_event_id safe under concurrent async tasks.
from autopil import ContextGuard, SensitivityLevel
guard = ContextGuard(policy_path="policies/")
@guard.protect_async(
agent_role="analyst",
user_id="user_002",
source_id="reports",
sensitivity_level=SensitivityLevel.MEDIUM,
session_id=session_id,
)
async def fetch_report(query: str) -> list:
return await vector_db.asearch(query)
# Safe to run concurrently — each task gets its own ContextVar slot
results = await asyncio.gather(
fetch_report("Q1 revenue"),
fetch_report("Q2 margins"),
)
Source type: protect_async uses the same _source_type="sdk" as the sync decorator. All audit events are stamped consistently regardless of sync vs async path.
TypeScript SDK
TypeScript SDK: A thin REST API wrapper published as @autopil/sdk. Zero runtime dependencies — uses native fetch (Node 18+).
npm install @autopil/sdk
Set your Render URL and API key as environment variables, then pass them to the client. Get your key from the dashboard under Settings → API Keys (evaluate scope for agent code).
import { AutoPilClient } from "@autopil/sdk"
const client = new AutoPilClient({
baseUrl: process.env.AUTOPIL_BASE_URL!, // https://your-app.onrender.com
apiKey: process.env.AUTOPIL_API_KEY!,
})
// Evaluate a retrieval request
const result = await client.context.evaluate({
agent_role: "loan_underwriter",
source_id: "credit_scores",
user_id: "user_001",
sensitivity_level: "high",
session_id: "sess_abc",
})
if (result.decision === "DENY") {
throw new Error(result.reason)
}
// Query audit events
const events = await client.audit.listEvents({
agent_role: "loan_underwriter",
decision: "DENY",
limit: 50,
})
Client resources
Client resources:
| Resource | Methods |
|---|---|
client.context | evaluate() |
client.sessions | list(), get(), revoke() |
client.audit | getSession(), listEvents(), getStats() |
client.lineage | record(), get() |
client.policies | list(), create(), update(), delete(), reload(), getHistory() |
client.alerts | createRule(), listRules(), updateRule(), deleteRule(), listFired() |
client.keys | create(), list(), revoke() |
client.admin | createTenant(), listTenants(), deactivateTenant() |
client.health() | — no auth required |
AutoPilError is thrown for non-2xx responses and carries statusCode and detail from the server.