Agent SDK Capabilities
Everything that makes Keeptrusts governance powerful is available in the Agent SDK: policy enforcement, request correlation, cost attribution, evidence collection, and gateway-owned MCP — all attached to a registered agent identity.
Governed inference
Every request through the agent runtime passes the full gateway policy chain:
const result = await agent.chat({
model: "gpt-5.4-mini",
messages: [{ role: "user", content: "Draft a security assessment." }],
});
Behind the scenes:
| Phase | What happens |
|---|---|
| Header injection | x-keeptrusts-agent-id, x-request-id, traceparent attached |
| Input policies | Content firewall, PII redaction, prompt injection detection |
| Provider routing | Gateway routes to configured upstream (OpenAI, Anthropic, etc.) |
| Output policies | Output redaction, disclaimer injection, safety filters |
| Event recording | Decision event with cost, outcome, and policy details |
Streaming
const stream = await agent.chatStream({
model: "gpt-5.4-mini",
messages: [{ role: "user", content: "Explain our compliance posture." }],
});
for await (const chunk of stream) {
process.stdout.write(chunk.choices[0]?.delta?.content ?? "");
}
Streaming receives identical policy enforcement. Output policies evaluate on assembled chunks.
Multi-model support
The gateway handles provider routing — your agent code stays provider-agnostic:
// OpenAI models
await agent.chat({ model: "gpt-5.4-mini", messages });
// Anthropic models
await agent.chat({ model: "claude-sonnet-4-20250514", messages });
// Any configured provider
await agent.chat({ model: "llama-3.1-70b", messages });
Agent identity
Every request is attributed to a registered agent via x-keeptrusts-agent-id:
const agent = createAgentRuntime({
agentId: "agent-compliance-bot", // permanent identity
// ...
});
This identity enables:
- Per-agent spend dashboards
- Per-agent policy exception rules
- Per-agent event filtering
- Per-agent action audit trails
Rejecting unidentified requests
The SDK rejects empty or missing agentId at construction time:
// ❌ Throws: agentId is required
createAgentRuntime({ agentId: "", /* ... */ });
// ❌ Throws: agentId is required
createAgentRuntime({ agentId: undefined, /* ... */ });
Request correlation
Every request gets a unique x-request-id that stitches together:
- The inference request to the gateway
- The decision event in the control plane
- The trail record for audit verification
- The cost attribution record
const result = await agent.chat({ model: "gpt-5.4-mini", messages });
// Use the request ID to query all related records
const events = await agent.listEvents({ requestId: result.requestId });
const bundle = await agent.createEvidenceBundle({ requestId: result.requestId });
Custom request IDs
Provide your own when you need deterministic correlation:
const result = await agent.chat({
model: "gpt-5.4-mini",
messages,
requestId: "my-workflow-step-001",
});
Observability
Event reads
Query decision events after any request:
// Events for a specific request
const events = await agent.listEvents({ requestId });
// Events for this agent in the last hour
const recent = await agent.listEvents({
since: new Date(Date.now() - 3600_000).toISOString(),
limit: 50,
});
// Full event detail
const detail = await agent.getEvent(events[0].event_id);
console.log(detail.event_cost_attribution);
console.log(detail.policy_outcome);
console.log(detail.input_tokens, detail.output_tokens);
Agent stats
const stats = await agent.getStats();
console.log(stats.total_requests);
console.log(stats.total_cost);
console.log(stats.policy_blocks);
console.log(stats.escalations);
Agent actions
const actions = await agent.listActions();
for (const action of actions) {
console.log(`${action.type}: ${action.description} at ${action.created_at}`);
}
Evidence and audit
Evidence bundles
Create a complete audit package for any request:
const bundle = await agent.createEvidenceBundle({
requestId: result.requestId,
});
// bundle.event — the decision event
// bundle.trail — trail records
// bundle.digest — cryptographic digest
// bundle.publicKey — verification key
// bundle.verification — chain integrity result
Trail verification
Verify trail integrity for a time window:
const verification = await agent.verifyTrail({
startTime: "2026-05-31T00:00:00Z",
endTime: "2026-05-31T23:59:59Z",
});
console.log(verification.chain_integrity); // true
console.log(verification.records_verified);
Digest download
const digest = await agent.downloadDigest("digest-id");
console.log(digest.storage_key);
console.log(digest.hash_algorithm);
Deployment management
Set deployment status
await agent.setDeployment({
status: "active",
version: "2.1.0",
metadata: { environment: "production", region: "us-east-1" },
});
Query deployment history
const snapshots = await agent.listSnapshots();
for (const snap of snapshots) {
console.log(`${snap.version} — ${snap.status} at ${snap.deployed_at}`);
}
Gateway management
Link and unlink gateways from the agent:
// List linked gateways
const gateways = await agent.listGateways();
// Add a gateway
await agent.addGateway("gateway-prod-us-east");
// Remove a gateway
await agent.removeGateway("gateway-staging");
MCP tool consumption
The gateway owns MCP transport — the agent SDK consumes it:
const result = await agent.chat({
model: "gpt-5.4-mini",
messages: [{ role: "user", content: "Search our knowledge base for GDPR policies." }],
// MCP-capable tools are available when the gateway has MCP providers configured
});
See MCP Integration for details on how the gateway mediates tool calls.
Cost attribution
Every request produces a cost record on the decision event:
const events = await agent.listEvents({ requestId });
const cost = events[0].event_cost_attribution;
console.log(cost.total_cost); // decimal string
console.log(cost.input_cost); // input token cost
console.log(cost.output_cost); // output token cost
console.log(cost.source_spend_log_id); // stable ledger reference
:::tip Spend attribution rule
Always use event_cost_attribution from events for per-request cost. Wallet APIs are for balance and transaction workflows, not per-request reporting.
:::
Header preservation
The SDK preserves canonical headers across retries and redirects:
| Header | Purpose |
|---|---|
x-keeptrusts-agent-id | Agent identity attribution |
x-request-id | Request correlation key |
traceparent | W3C distributed trace context |
If you need to inspect or override headers:
const result = await agent.chat({
model: "gpt-5.4-mini",
messages,
headers: {
"x-custom-workflow": "compliance-review",
},
});
Custom headers are merged with — but never override — the canonical Keeptrusts headers.
Error handling
The SDK surfaces governance errors as typed exceptions:
import { PolicyBlockError, EscalationError, InsufficientBalanceError } from "@keeptrusts/agent";
try {
await agent.chat({ model: "gpt-5.4-mini", messages });
} catch (error) {
if (error instanceof PolicyBlockError) {
console.log(`Blocked by policy: ${error.policyName}`);
console.log(`Reason: ${error.reason}`);
} else if (error instanceof EscalationError) {
console.log(`Escalated: ${error.escalationId}`);
} else if (error instanceof InsufficientBalanceError) {
console.log(`Insufficient wallet balance for scope: ${error.scope}`);
}
}