@truthvouch/sdk
v1.2.0
Published
TruthVouch Governance Gateway TypeScript SDK - Production-grade client for AI governance
Maintainers
Readme
TruthVouch TypeScript SDK
A production-grade TypeScript SDK for the TruthVouch Governance Gateway. Seamlessly route LLM calls through AI governance with zero runtime dependencies.
Features
- Multi-provider support: OpenAI, Anthropic, Google Gemini
- Streaming SSE: Real-time governance with streamed responses
- Batch scanning: Submit document corpora for offline governance analysis
- Circuit breaker resilience: Automatic failover with configurable fallback modes
- Comprehensive error handling: Typed exceptions for all failure scenarios
- Webhook verification: Secure HMAC-SHA256 validation for asynchronous events
- OpenTelemetry ready: Optional trace propagation and span recording
- Zero runtime dependencies: Uses native
fetchandcryptoonly
Installation
npm install @truthvouch/sdkQuick Start
1. Initialize the Client
import { TruthVouch } from '@truthvouch/sdk';
const client = new TruthVouch({
apiKey: process.env.TRUTHVOUCH_API_KEY,
gatewayUrl: 'https://gateway.truthvouch.com',
failMode: 'open', // or 'closed'
});2. Call an LLM Provider
// OpenAI
const response = await client.chat.create({
model: 'gpt-4o',
messages: [{ role: 'user', content: 'Explain quantum computing' }],
});
console.log(response.content);
console.log(response.governance.verdict);3. Check Governance Results
const { governance } = response;
if (governance.verdict === 'blocked') {
console.warn('Request blocked by governance policy');
console.warn('Violations:', governance.policyViolations);
}
if (governance.piiDetected) {
console.warn('PII detected in response');
}
if (governance.truthScan) {
console.log(`Hallucination confidence: ${governance.truthScan.confidence}`);
}Provider Examples
OpenAI
// Non-streaming
const response = await client.chat.create({
model: 'gpt-4o',
messages: [{ role: 'user', content: 'Hello' }],
temperature: 0.7,
maxTokens: 1024,
});
console.log(response.content);
console.log(`Governance verdict: ${response.governance.verdict}`);Streaming (OpenAI)
const stream = await client.chat.createStream({
model: 'gpt-4o',
messages: [{ role: 'user', content: 'Write a poem' }],
});
for await (const chunk of stream) {
if (!chunk.isLast) {
process.stdout.write(chunk.content ?? '');
}
}
// Governance report available after streaming completes
const governance = stream.getGovernanceReport();
console.log(`Final verdict: ${governance?.verdict}`);Anthropic
const response = await client.messages.create({
model: 'claude-3-5-sonnet-20241022',
maxTokens: 1024,
messages: [{ role: 'user', content: 'What is machine learning?' }],
system: 'You are a helpful AI assistant.',
});
console.log(response.content);
console.log(response.governance.piiDetected);Google Gemini
const response = await client.google.generateContent({
model: 'gemini-1.5-pro',
contents: [{ role: 'user', parts: 'Translate "hello" to French' }],
});
console.log(response.text);
console.log(response.governance.verdict);Manual Scanning
const scanResult = await client.scan.scan({
prompt: 'User input here',
response: 'LLM output here',
});
console.log(scanResult.governance.verdict);
console.log(scanResult.alerts);Batch Scanning
// Submit batch job
const job = await client.batch.submit({
sourceUrl: 's3://my-bucket/documents.jsonl',
format: 'jsonl',
scanMode: 'deep', // 'fast' | 'standard' | 'deep'
callbackUrl: 'https://example.com/webhook',
});
console.log(`Batch job submitted: ${job.id}`);
console.log(`Estimated completion: ${job.estimatedCompletion}`);
// Poll for status
const status = await client.batch.getStatus(job.id);
console.log(`Progress: ${status.progressPercent}%`);
console.log(`Flagged documents: ${status.flaggedCount}`);Configuration
Configuration resolves in priority order:
- Constructor options (highest)
- Environment variables
.truthvouch.jsonfile (inprocess.cwd())- Defaults (lowest)
Environment Variables
TRUTHVOUCH_API_KEY=sk_test_...
TRUTHVOUCH_BASE_URL=https://gateway.truthvouch.com
TRUTHVOUCH_TIMEOUT_MS=30000
TRUTHVOUCH_FAIL_MODE=open
TRUTHVOUCH_TELEMETRY_ENABLED=false.truthvouch.json
{
"gatewayUrl": "https://gateway.truthvouch.com",
"apiKey": "sk_test_...",
"failMode": "open",
"timeoutMs": 30000,
"circuitBreakerFailureThreshold": 5,
"circuitBreakerRecoveryMs": 60000,
"telemetryEnabled": false
}Configuration Reference
| Option | Type | Default | Description |
|--------|------|---------|-------------|
| apiKey | string | (required) | TruthVouch API key |
| gatewayUrl | string | https://gateway.truthvouch.com | Gateway base URL |
| failMode | 'open' | 'closed' | 'open' | Behavior when gateway unreachable |
| timeoutMs | number | 30000 | HTTP request timeout |
| maxRetries | number | 3 | Retry attempts for transient errors |
| circuitBreakerFailureThreshold | number | 5 | Failures before circuit opens |
| circuitBreakerRecoveryMs | number | 60000 | Time before recovery probe |
| enableRequestLogging | boolean | false | Log all gateway requests (debug) |
| serviceName | string | undefined | OpenTelemetry service name |
| telemetryEnabled | boolean | false | Enable telemetry recording |
Error Handling
import {
TruthVouchError,
GatewayUnreachableError,
PolicyBlockedError,
AuthenticationError,
QuotaExceededError,
InvalidRequestError,
UpstreamProviderError,
} from '@truthvouch/sdk';
try {
const response = await client.chat.create({
model: 'gpt-4o',
messages: [{ role: 'user', content: 'Hello' }],
});
} catch (error) {
if (error instanceof PolicyBlockedError) {
console.error('Governance policy violation:', error.governanceReport?.policyViolations);
} else if (error instanceof QuotaExceededError) {
console.error(`Rate limited. Retry after ${error.retryAfterMs}ms`);
} else if (error instanceof AuthenticationError) {
console.error('Invalid API key. Check your credentials.');
} else if (error instanceof GatewayUnreachableError) {
if (error.cause instanceof Error) {
console.error('Gateway connection failed:', error.cause.message);
}
} else if (error instanceof UpstreamProviderError) {
console.error(`Upstream error (HTTP ${error.upstreamStatusCode})`);
} else {
throw error;
}
}Webhook Verification
Verify signatures on incoming webhooks:
import { verifyWebhook } from '@truthvouch/sdk/webhooks';
export async function handleWebhook(req: Request): Promise<Response> {
const signature = req.headers.get('X-TruthVouch-Signature');
const secret = process.env.TRUTHVOUCH_WEBHOOK_SECRET;
if (!signature || !secret) {
return new Response('Missing signature or secret', { status: 401 });
}
const payload = await req.text();
const isValid = verifyWebhook({
payload,
signature,
secret,
});
if (!isValid) {
return new Response('Invalid signature', { status: 401 });
}
const event = JSON.parse(payload);
console.log('Webhook verified:', event);
return new Response('OK', { status: 200 });
}Resilience & Circuit Breaker
The SDK includes an automatic circuit breaker that protects against cascading failures:
CLOSED (normal)
↓ (5 consecutive failures)
OPEN (gateway down, requests blocked or bypassed per failMode)
↓ (60 seconds)
HALF_OPEN (recovery probe allowed)
↓ (success)
CLOSED (back to normal)Configure thresholds:
const client = new TruthVouch({
apiKey: process.env.TRUTHVOUCH_API_KEY,
circuitBreakerFailureThreshold: 3, // Open after 3 failures (default: 5)
circuitBreakerRecoveryMs: 30000, // 30 second recovery window (default: 60000)
});Fail Modes
open(default): When the gateway is unreachable, bypass it and call the upstream LLM directly (no governance)closed: When the gateway is unreachable, throwGatewayUnreachableErrorand block all LLM calls
OpenTelemetry Integration
Automatically record spans and attributes when OpenTelemetry is available:
import { trace } from '@opentelemetry/api';
import {
getActiveSpan,
recordGovernanceAttributes,
} from '@truthvouch/sdk';
const tracer = trace.getTracer('my-app');
const span = tracer.startSpan('llm_request');
const response = await client.chat.create({
model: 'gpt-4o',
messages: [{ role: 'user', content: 'Hello' }],
});
recordGovernanceAttributes(getActiveSpan(), response.governance);
span.end();Logging
Control SDK logging verbosity:
import { logger } from '@truthvouch/sdk';
// Available levels: 'debug', 'info', 'warn', 'error'
logger.setLevel('debug');Advanced Usage
Custom Retry Logic
import { withRetry } from '@truthvouch/sdk';
const response = await withRetry(
() => client.chat.create({
model: 'gpt-4o',
messages: [{ role: 'user', content: 'Hello' }],
}),
{
maxRetries: 5,
baseDelayMs: 500,
factor: 2,
jitterFraction: 0.25,
}
);Direct Transport Access
For advanced scenarios, access the transport layer directly:
import { RestTransport } from '@truthvouch/sdk';
const transport = new RestTransport(
'https://gateway.truthvouch.com',
'sk_test_...',
30000
);
const response = await transport.post('v1/custom/endpoint', {
custom: 'data',
});Migration from Direct OpenAI SDK
Before:
import OpenAI from 'openai';
const client = new OpenAI({ apiKey: process.env.OPENAI_API_KEY });
const response = await client.chat.completions.create({
model: 'gpt-4o',
messages: [{ role: 'user', content: 'Hello' }],
});After:
import { TruthVouch } from '@truthvouch/sdk';
const client = new TruthVouch({ apiKey: process.env.TRUTHVOUCH_API_KEY });
const response = await client.chat.create({
model: 'gpt-4o',
messages: [{ role: 'user', content: 'Hello' }],
});
console.log(response.governance.verdict); // Check governanceTroubleshooting
Gateway timeout
Increase timeoutMs:
const client = new TruthVouch({
apiKey: process.env.TRUTHVOUCH_API_KEY,
timeoutMs: 60000, // 60 seconds
});Circuit breaker constantly open
Increase circuitBreakerRecoveryMs or reduce circuitBreakerFailureThreshold:
const client = new TruthVouch({
apiKey: process.env.TRUTHVOUCH_API_KEY,
circuitBreakerFailureThreshold: 10,
circuitBreakerRecoveryMs: 120000,
});Missing governance report in stream
Ensure you consume the entire stream or call stream.getGovernanceReport() after iteration completes.
License
Apache-2.0
