Skip to main content

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:

PhaseWhat happens
Header injectionx-keeptrusts-agent-id, x-request-id, traceparent attached
Input policiesContent firewall, PII redaction, prompt injection detection
Provider routingGateway routes to configured upstream (OpenAI, Anthropic, etc.)
Output policiesOutput redaction, disclaimer injection, safety filters
Event recordingDecision 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:

HeaderPurpose
x-keeptrusts-agent-idAgent identity attribution
x-request-idRequest correlation key
traceparentW3C 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}`);
}
}