@tenet-ai/sdk
v0.3.0
Published
Node.js SDK for Tenet AI - Audit trail and replay for AI agents
Maintainers
Readme
@tenet-ai/sdk
Git for AI Agent Decisions - Complete audit trail, replay, and drift detection for enterprise AI agents.
Why Tenet AI?
When your AI agent approves a $10,000 refund or denies a loan application, can you answer:
- Why did the agent make that decision?
- What context did it have at the time?
- Would it decide the same way if we ran it again?
- Who overrode the agent's recommendation?
Tenet AI captures every decision your agent makes with full context, enabling audit trails, replay verification, drift detection, and guardrails enforcement.
Installation
npm install @tenet-ai/sdkQuick Start
High-Level: trace()
Wrap any agent function call in a single line:
import { Tenet } from "@tenet-ai/sdk";
const tenet = new Tenet({ apiKey: "tnt_your_key" });
const result = await tenet.trace({
agentId: "support-agent",
fn: async () => {
// Your agent logic here
return { action: "approve_refund", amount: 149.99 };
},
tags: ["production", "refunds"],
metadata: { customer_id: "C-123" },
});
console.log(result.executionId); // Stored in Tenet for audit
console.log(result.output); // { action: "approve_refund", amount: 149.99 }Low-Level: Full Control
For fine-grained tracking with context, decisions, and executions:
import { Tenet, ResultType, ActorType } from "@tenet-ai/sdk";
const tenet = new Tenet({ apiKey: "tnt_your_key" });
// 1. Create an intent (fire-and-forget, returns immediately)
const intent = tenet.createIntent({
goal: "Process refund request",
agentId: "support-agent",
});
// 2. Capture what the agent saw
intent.snapshotContext({
customer_tier: "gold",
order_amount: 149.99,
days_since_delivery: 5,
});
// 3. Record the decision with options considered
intent.decide({
options: [
{ action: "approve_refund", score: 0.95, reason: "Gold customer, within policy" },
{ action: "deny_refund", score: 0.05, reason: "N/A" },
],
chosenAction: "approve_refund",
confidence: 0.95,
reasoning: "Customer eligible per 30-day return policy",
});
// 4. Record execution
const executionId = intent.execute({
action: "approve_refund",
target: { order_id: "ORD-123" },
result: ResultType.SUCCESS,
});
// In tests: wait for all writes to land
await tenet.flush();Key Features
Decision Replay with Drift Detection
Store the prompt and re-run decisions to verify consistency:
const intent = tenet.createIntent({
goal: "Handle support ticket",
agentId: "support-agent",
});
intent.snapshotContext({ ticket_id: "T-123", priority: "high" });
intent.decide({
options: [{ action: "escalate", score: 0.9 }],
chosenAction: "escalate",
confidence: 0.9,
reasoning: "High priority ticket requires escalation",
replayPrompt: "You are a support agent. Ticket: high priority. Action?",
replayConfig: { model: "gpt-4o-mini", temperature: 0.0 },
});
const execId = intent.execute({
action: "escalate",
target: { ticket_id: "T-123" },
result: ResultType.SUCCESS,
});
// Flush writes before reading back
await tenet.flush();
// Later: verify the decision is still consistent
const replay = await tenet.replay({ executionId: execId });
console.log(replay.drift_score); // 0.0 = identical, 1.0 = fully diverged
if (replay.diverged) {
console.log("WARNING: Model behavior changed!");
}Multi-Agent Tracking (Parent-Child Intents)
Track complex workflows with multiple agents or MCP tool calls:
const parent = tenet.createIntent({
goal: "Process customer request",
agentId: "orchestrator",
});
parent.snapshotContext({ request: "refund for order 123" });
// Spawn child intent for sub-agent
const child = parent.childIntent({
goal: "Search order history",
mcpServer: "database",
});
child.snapshotContext({ query: "order 123" });
child.decide({
options: [{ action: "query_db", score: 1.0 }],
chosenAction: "query_db",
confidence: 1.0,
});
child.execute({
action: "query_db",
target: { order_id: "123" },
result: ResultType.SUCCESS,
});
// Parent continues with child's result
parent.decide({
options: [
{ action: "approve_refund", score: 0.9, reason: "Order found, within policy" },
],
chosenAction: "approve_refund",
confidence: 0.9,
});
parent.execute({
action: "approve_refund",
target: { order_id: "123" },
result: ResultType.SUCCESS,
});Human Override Tracking
When humans override agent decisions:
intent.execute({
action: "deny_refund", // Human chose differently
target: { order_id: "123" },
result: ResultType.SUCCESS,
actor: ActorType.HUMAN,
overrideReason: "Customer has history of fraud",
});Guardrails — Block, Warn, or Log Agent Actions
Define rules that are evaluated server-side before decisions are recorded. Rules with block enforcement reject the decision with HTTP 403.
// Create a guardrail rule via the API
const response = await fetch(`${endpoint}/api/v1/guardrails`, {
method: "POST",
headers: { "X-API-Key": apiKey, "Content-Type": "application/json" },
body: JSON.stringify({
name: "Block dangerous actions",
rule_type: "action_blocklist",
enforcement_level: "block",
rule_config: { blocked_actions: ["delete_account", "drop_table"] },
}),
});Supported rule types:
action_allowlist— only allow specific actionsaction_blocklist— block specific actionsconfidence_threshold— require minimum confidencecontext_field_check— check a context input field (e.g. amount > 10000)regex_match— regex on action or fieldjson_path_check— dot-path check into contextvalue_range— min/max range on any numeric field
Enforcement levels: block (reject with 403), warn (flag but allow), log (silent record).
Ghost SDK — Zero-Impact Observability
All write operations (intent, context, decision, execution) generate UUIDs client-side and fire-and-forget via background promises. Your agent never waits for Tenet.
The Ghost SDK Promise:
- Main-thread overhead: <5ms per full decision lifecycle (4 writes)
- Silent failure: Network errors are caught silently — never thrown to your agent
- Client-side UUIDs: IDs are available immediately, no round-trip needed
- 100% uptime guarantee for your primary process
import { Tenet } from '@tenet-ai/sdk';
// Ghost SDK is enabled by default
const tenet = new Tenet({ apiKey: 'tnt_your_key' });
// All write calls return immediately — no await needed
const intent = tenet.createIntent({
goal: 'Process refund',
agentId: 'support-agent',
});
intent.snapshotContext({ customer_tier: 'gold' });
intent.decide({ options: [...], chosenAction: 'approve', confidence: 0.95 });
intent.execute({ action: 'approve', target: { order: '123' }, result: ResultType.SUCCESS });
// In tests, await flush() to ensure writes have landed
await tenet.flush();
// For graceful shutdown
await tenet.shutdown();Configuration:
| Parameter | Default | Description |
|-----------|---------|-------------|
| asyncWrites | true | Set to false for synchronous mode (legacy compat) |
| onError | undefined | Callback (error, payload) for observability |
| maxRetries | 3 | Retry count before silent drop |
Capture Health Monitoring
Check whether data is actually reaching the Tenet backend:
const stats = tenet.getStats();
// { sent: 42, failed: 0, lastSuccessAt: Date }
if (stats.failed > 0) {
console.warn(`${stats.failed} captures did not reach Tenet — check connectivity and API key`);
}sent— total successful writes to the backendfailed— writes that exhausted all retries (data NOT in Tenet)lastSuccessAt—Dateof the most recent successful write, ornull
Failed captures also emit a console.warn with the path, attempt count, and error message so they surface in your production logs automatically.
Framework Integrations
LangChain.js
import { Tenet } from "@tenet-ai/sdk";
import { TenetCallbackHandler } from "@tenet-ai/sdk/integrations/langchain";
const tenet = new Tenet({ apiKey: "tnt_your_key" });
const handler = new TenetCallbackHandler({
client: tenet,
agentId: "langchain-agent",
});
// Pass as a callback to any LangChain.js chain or agent
const result = await chain.invoke({ input: "Process refund" }, { callbacks: [handler] });OpenAI Node SDK
import OpenAI from "openai";
import { Tenet } from "@tenet-ai/sdk";
import { TenetOpenAITracker } from "@tenet-ai/sdk/integrations/openai";
const openai = new OpenAI();
const tenet = new Tenet({ apiKey: "tnt_your_key" });
const tracker = new TenetOpenAITracker({
client: tenet,
agentId: "openai-agent",
});
// Wrap the OpenAI client — all chat completions are tracked automatically
const tracked = tracker.wrap(openai);
const response = await tracked.chat.completions.create({
model: "gpt-4o",
messages: [{ role: "user", content: "Process this refund" }],
});Vercel AI SDK
import { generateText } from "ai";
import { Tenet } from "@tenet-ai/sdk";
import { TenetVercelAITracker } from "@tenet-ai/sdk/integrations/vercel-ai";
const tenet = new Tenet({ apiKey: "tnt_your_key" });
const tracker = new TenetVercelAITracker({
client: tenet,
agentId: "vercel-agent",
});
// Wrap generateText — all calls are tracked automatically
const trackedGenerateText = tracker.wrapGenerateText(generateText);
const result = await trackedGenerateText({
model: yourModel,
prompt: "Process this refund",
});API Reference
Constructor
const tenet = new Tenet({
apiKey: "tnt_your_key", // Required
endpoint: "https://ael-backend.onrender.com", // Optional (default: production)
environment: "production", // Optional
timeout: 30000, // Optional (ms)
asyncWrites: true, // Optional (Ghost SDK, default: true)
onError: (err, payload) => console.error(err), // Optional
});High-Level Methods
| Method | Description |
|--------|-------------|
| tenet.trace({ agentId, fn, ... }) | Wrap a function call with automatic audit trail |
| tenet.replay({ executionId }) | Replay a past decision and detect drift |
| tenet.flush() | Wait for all background writes to complete |
| tenet.shutdown() | Flush and clean up |
| tenet.getStats() | Return { sent, failed, lastSuccessAt } capture counters |
Low-Level Methods (Synchronous — Fire-and-Forget)
| Method | Description |
|--------|-------------|
| tenet.createIntent({ goal, agentId }) | Create an intent, returns IntentHandle immediately |
| intent.snapshotContext(inputs) | Capture what the agent sees |
| intent.decide({ options, chosenAction, confidence }) | Record a decision |
| intent.execute({ action, target, result }) | Record execution |
| intent.childIntent({ goal, mcpServer }) | Create a child intent (multi-agent) |
Read Methods
| Method | Description |
|--------|-------------|
| tenet.getIntent(id) | Get intent details |
| tenet.getIntentChildren(id) | Get child intents |
| tenet.getIntentHierarchy(id) | Get parent chain (breadcrumbs) |
| tenet.getIntentTree(id) | Get full descendant tree |
| tenet.getDecision(id) | Get decision details |
| tenet.listDecisions({ agentId, tags, ... }) | List and filter decisions |
| tenet.getExecution(id) | Get execution details |
| tenet.getSessionTimeline(sessionId) | Get full session timeline |
Guardrail Endpoints
| Method | Description |
|--------|-------------|
| POST /api/v1/guardrails | Create a guardrail rule |
| GET /api/v1/guardrails | List guardrails (filter by is_active, rule_type) |
| GET /api/v1/guardrails/{id} | Get guardrail by ID |
| PATCH /api/v1/guardrails/{id} | Update a guardrail |
| DELETE /api/v1/guardrails/{id} | Delete a guardrail |
| GET /api/v1/guardrails/{id}/evaluations | List evaluation history |
Advanced
| Method | Description |
|--------|-------------|
| tenet.checkDrift({ sampleSize, timeWindowHours }) | Batch drift detection |
| tenet.generateComplianceReport({ regulation }) | Generate compliance report |
| tenet.revert({ executionId, reason }) | Revert an execution |
Getting Started
1. Create an Account
Go to tenetai.dev and sign in with Google.
2. Create a Workspace
After signing in, create a workspace (e.g., "Production Agents").
3. Generate an API Key
Navigate to API Keys > Create API Key > Copy your key (tnt_xxxx...).
4. Install the SDK
npm install @tenet-ai/sdkUse Cases
| Industry | Use Case | |----------|----------| | FinTech | Audit loan decisions, fraud detection reasoning | | Healthcare | Track triage recommendations, document clinical AI decisions | | E-commerce | Refund approvals, pricing decisions, inventory management | | Legal | Contract analysis decisions, compliance checking | | HR | Resume screening, candidate ranking explanations |
License
MIT License - see LICENSE for details.
Links
- Dashboard: tenetai.dev
- npm: npmjs.com/package/@tenet-ai/sdk
- Python SDK: pypi.org/project/tenet-ai
