@fulcrum-governance/sdk
v0.1.4
Published
TypeScript SDK for Fulcrum - Intelligent AI Governance Platform
Maintainers
Readme
Fulcrum TypeScript SDK
Intelligent AI Governance for Enterprise Agents
Installation
npm install @fulcrum-governance/sdkQuick Start
import { FulcrumClient } from '@fulcrum-governance/sdk';
// Initialize client
const client = new FulcrumClient({
host: 'your-fulcrum-server:50051',
apiKey: 'your-api-key',
onFailure: 'FAIL_OPEN' // or 'FAIL_CLOSED'
});
// Wrap agent executions in governance envelopes
const envelope = client.envelope({
workflowId: 'customer-support-bot',
tenantId: 'your-tenant-id'
});
// Check if action is allowed before executing
const allowed = await envelope.guard('send_email', userMessage);
if (allowed) {
// Action approved - proceed
const result = await sendEmail(userMessage);
envelope.log('email_sent', { recipient: email, status: 'success' });
} else {
// Action blocked by policy
envelope.log('action_blocked', { reason: 'policy_violation' });
}Features
- Policy Enforcement: Real-time governance checks before agent actions
- Cost Tracking: Monitor and control LLM spending per workflow
- Audit Trail: Complete execution history for compliance
- Fail-Safe Modes: Configurable FAIL_OPEN or FAIL_CLOSED behavior
- TypeScript Support: Full type definitions included
Configuration
Client Options
import { FulcrumClient, FailureMode } from '@fulcrum-governance/sdk';
const client = new FulcrumClient({
host: 'localhost:50051', // Fulcrum server address
apiKey: 'your-api-key', // API key for authentication
tenantId: 'your-tenant-id', // Default tenant ID
onFailure: FailureMode.FAIL_OPEN, // FAIL_OPEN or FAIL_CLOSED
timeoutMs: 500, // Request timeout in milliseconds
enableTls: true, // Enable TLS encryption
caCertPath: '/path/to/ca.crt', // Custom CA certificate (optional)
});Environment Variables
export FULCRUM_HOST="localhost:50051"
export FULCRUM_API_KEY="your-api-key"
export FULCRUM_TENANT_ID="your-tenant-id"
export FULCRUM_TIMEOUT_MS="500"// Client auto-discovers from environment
const client = FulcrumClient.fromEnv();API Reference
FulcrumClient
interface FulcrumClientOptions {
host: string; // gRPC server address (e.g., 'localhost:50051')
apiKey?: string; // Authentication key
tenantId?: string; // Default tenant ID
onFailure?: 'FAIL_OPEN' | 'FAIL_CLOSED'; // Behavior on errors
timeoutMs?: number; // Request timeout (default: 500ms)
enableTls?: boolean; // Enable TLS (default: false for localhost)
caCertPath?: string; // Custom CA certificate path
}Methods
| Method | Description |
|--------|-------------|
| envelope(options) | Create a governance envelope |
| evaluate(action, inputText, context) | Evaluate a policy decision |
| getCost(envelopeId) | Get cost for an envelope |
| listPolicies(tenantId) | List active policies |
| healthCheck() | Check server connectivity |
Envelope
interface EnvelopeOptions {
workflowId: string; // Identifier for the workflow
executionId?: string; // Auto-generated if not provided
tenantId?: string; // Defaults to client tenant
metadata?: Record<string, string>; // Additional context
}Methods
| Method | Signature | Description |
|--------|-----------|-------------|
| guard | (actionName: string, inputText: string, metadata?: Record<string, string>) => Promise<boolean> | Check if action is allowed |
| log | (eventType: string, payload: Record<string, any>) => void | Log event for audit |
| checkpoint | () => Promise<Checkpoint> | Create execution checkpoint |
| getCost | () => Promise<CostSnapshot> | Get current execution cost |
| complete | (result?: any) => Promise<void> | Mark envelope complete |
Error Handling
import { FulcrumClient } from '@fulcrum-governance/sdk';
import {
FulcrumError, // Base error class
PolicyViolationError, // Action blocked by policy
BudgetExceededError, // Budget limit reached
ConnectionError, // Server unreachable
AuthenticationError, // Invalid API key
TimeoutError, // Request timed out
} from '@fulcrum-governance/sdk/errors';
const client = new FulcrumClient({
host: 'localhost:50051',
apiKey: 'your-key'
});
try {
const envelope = client.envelope({ workflowId: 'my-agent' });
const allowed = await envelope.guard('send_email', 'Hello');
if (allowed) {
await sendEmail('Hello');
}
await envelope.complete();
} catch (error) {
if (error instanceof PolicyViolationError) {
console.log(`Policy violation: ${error.policyId}`);
console.log(`Reason: ${error.message}`);
console.log(`Matched rules: ${error.matchedRules.join(', ')}`);
} else if (error instanceof BudgetExceededError) {
console.log(`Budget exceeded: $${error.currentSpend} / $${error.budgetLimit}`);
} else if (error instanceof ConnectionError) {
console.log(`Cannot reach Fulcrum server: ${error.message}`);
// Handle based on failure mode
} else if (error instanceof TimeoutError) {
console.log('Request timed out');
} else {
throw error;
}
}Integration Examples
Vercel AI SDK
import { streamText } from 'ai';
import { openai } from '@ai-sdk/openai';
import { FulcrumClient } from '@fulcrum-governance/sdk';
const fulcrum = FulcrumClient.fromEnv();
export async function POST(req: Request) {
const { messages } = await req.json();
const lastMessage = messages[messages.length - 1].content;
const envelope = fulcrum.envelope({
workflowId: 'vercel-ai-chat',
metadata: { source: 'api' }
});
// Pre-check message
if (!await envelope.guard('process_message', lastMessage)) {
return new Response('Message blocked by policy', { status: 403 });
}
const result = await streamText({
model: openai('gpt-4'),
messages,
onFinish: async ({ usage }) => {
envelope.log('completion', {
inputTokens: usage.promptTokens,
outputTokens: usage.completionTokens,
});
await envelope.complete();
}
});
return result.toAIStreamResponse();
}LangChain.js Integration
import { ChatOpenAI } from '@langchain/openai';
import { AgentExecutor } from 'langchain/agents';
import { FulcrumClient } from '@fulcrum-governance/sdk';
const fulcrum = FulcrumClient.fromEnv();
async function runGovernedAgent(
agent: AgentExecutor,
query: string
): Promise<string> {
const envelope = fulcrum.envelope({
workflowId: 'langchain-agent'
});
// Check if query is allowed
if (!await envelope.guard('process_query', query)) {
throw new Error('Query blocked by policy');
}
// Run agent
const result = await agent.invoke({
input: query,
callbacks: [{
handleToolStart: async (tool, input) => {
const allowed = await envelope.guard(tool.name, JSON.stringify(input));
if (!allowed) {
envelope.log('tool_blocked', { tool: tool.name });
throw new Error(`Tool ${tool.name} blocked by policy`);
}
},
handleToolEnd: (output) => {
envelope.log('tool_executed', { output: output.substring(0, 100) });
}
}]
});
await envelope.complete({ result: result.output });
return result.output;
}Express Middleware
import express from 'express';
import { FulcrumClient } from '@fulcrum-governance/sdk';
const app = express();
const fulcrum = FulcrumClient.fromEnv();
// Governance middleware
const governanceMiddleware = (workflowId: string) => {
return async (req: express.Request, res: express.Response, next: express.NextFunction) => {
const envelope = fulcrum.envelope({
workflowId,
metadata: {
path: req.path,
method: req.method,
userId: req.headers['x-user-id'] as string,
}
});
// Attach to request for use in handlers
(req as any).fulcrumEnvelope = envelope;
// Check request
const inputText = JSON.stringify(req.body);
if (!await envelope.guard('api_request', inputText)) {
return res.status(403).json({ error: 'Request blocked by policy' });
}
// Complete envelope on response finish
res.on('finish', () => {
envelope.log('response', { status: res.statusCode });
envelope.complete();
});
next();
};
};
app.use('/api/agents', governanceMiddleware('agent-api'));Cost Tracking
const envelope = client.envelope({ workflowId: 'my-agent' });
// ... agent execution ...
const cost = await envelope.getCost();
console.log(`Total cost: $${cost.totalUsd.toFixed(4)}`);
console.log(`Input tokens: ${cost.inputTokens}`);
console.log(`Output tokens: ${cost.outputTokens}`);
console.log(`LLM calls: ${cost.llmCalls}`);
// Model breakdown
for (const [model, stats] of Object.entries(cost.modelBreakdown)) {
console.log(` ${model}: $${stats.cost.toFixed(4)} (${stats.calls} calls)`);
}Type Definitions
interface PolicyDecision {
allowed: boolean;
policyId?: string;
decision: 'ALLOW' | 'DENY' | 'WARN' | 'REQUIRE_APPROVAL';
matchedRules: RuleMatch[];
actions: PolicyAction[];
message?: string;
}
interface RuleMatch {
ruleId: string;
ruleName: string;
matchedConditions: string[];
}
interface CostSnapshot {
totalUsd: number;
inputTokens: number;
outputTokens: number;
llmCalls: number;
toolCalls: number;
modelBreakdown: Record<string, { calls: number; cost: number }>;
}
interface Checkpoint {
checkpointId: string;
version: number;
stateHash: string;
createdAt: Date;
}REST Clients
The SDK includes REST-based clients for managing Fulcrum resources through the Dashboard API. These clients are ideal for administrative tasks, dashboards, and browser environments.
PolicyClient
Manage governance policies programmatically:
import { PolicyClient } from '@fulcrum-governance/sdk';
const policyClient = new PolicyClient({
baseUrl: 'https://your-fulcrum-dashboard.com',
apiKey: 'your-api-key',
timeoutMs: 5000 // optional, default: 5000
});
// List all policies
const policies = await policyClient.list();
// List with filters
const activePolicies = await policyClient.list({
status: 'active',
priority: 'high'
});
// Get a specific policy
const policy = await policyClient.get('policy-id');
// Create a new policy
const newPolicy = await policyClient.create({
name: 'No PII in Responses',
description: 'Prevents sensitive data exposure',
rules: [{ type: 'semantic', pattern: 'pii_detection' }],
priority: 1,
enabled: true
});
// Update a policy
const updated = await policyClient.update('policy-id', {
name: 'Updated Policy Name',
priority: 2
});
// Enable/disable policies
await policyClient.setEnabled('policy-id', false);
// Delete a policy
await policyClient.delete('policy-id');ApprovalClient
Manage human-in-the-loop approval workflows:
import { ApprovalClient } from '@fulcrum-governance/sdk';
const approvalClient = new ApprovalClient({
baseUrl: 'https://your-fulcrum-dashboard.com',
apiKey: 'your-api-key'
});
// List all pending approvals
const pending = await approvalClient.listPending();
// List with filters
const approvals = await approvalClient.list({
status: 'pending',
workflow_id: 'customer-support-bot'
});
// Get approval details
const approval = await approvalClient.get('approval-id');
// Approve a request
await approvalClient.approve('approval-id', 'Looks safe to proceed');
// Deny a request
await approvalClient.deny('approval-id', 'Contains sensitive information');
// Generic decision method
await approvalClient.decide('approval-id', {
decision: 'approved', // or 'denied'
comment: 'Reviewed and approved'
});BudgetClient
Manage AI spending budgets and limits:
import { BudgetClient } from '@fulcrum-governance/sdk';
const budgetClient = new BudgetClient({
baseUrl: 'https://your-fulcrum-dashboard.com',
apiKey: 'your-api-key'
});
// List all budgets with summary
const { budgets, summary } = await budgetClient.list();
console.log(`Total budgets: ${summary.total}`);
console.log(`Active: ${summary.active}, Exceeded: ${summary.exceeded}`);
// Filter by scope or status
const tenantBudgets = await budgetClient.listBudgets({ scope: 'TENANT' });
const exceededBudgets = await budgetClient.getExceeded();
const warningBudgets = await budgetClient.getWarnings();
// Get a specific budget
const budget = await budgetClient.get('budget-id');
// Create a new budget
const newBudget = await budgetClient.create({
name: 'Marketing Team Monthly',
scope: 'TENANT', // GLOBAL, TENANT, WORKFLOW, MODEL
scope_id: 'tenant-123',
limit_amount: 1000, // in dollars
period: 'MONTHLY', // DAILY, WEEKLY, MONTHLY, QUARTERLY
action: 'SOFT_LIMIT', // WARN, SOFT_LIMIT, HARD_LIMIT
alert_thresholds: [50, 75, 90]
});
// Update budget
await budgetClient.update('budget-id', {
limit_amount: 1500,
alert_thresholds: [60, 80, 95]
});
// Helper methods
const percentage = budgetClient.calculatePercentage(budget);
const isNearLimit = budgetClient.isAtThreshold(budget, 80);
// Delete a budget
await budgetClient.delete('budget-id');MetricsClient
Access platform metrics and audit logs:
import { MetricsClient } from '@fulcrum-governance/sdk';
const metricsClient = new MetricsClient({
baseUrl: 'https://your-fulcrum-dashboard.com',
apiKey: 'your-api-key' // optional for public metrics
});
// Public metrics (no auth required)
const metrics = await metricsClient.getPublicMetrics();
console.log(`Policies evaluated (24h): ${metrics.policiesEvaluated24h}`);
console.log(`Avg latency: ${metrics.avgLatencyMs}ms`);
console.log(`Blocked requests: ${metrics.blockedRequests24h}`);
// Cognitive layer metrics
const cognitive = await metricsClient.getCognitiveMetrics();
console.log(`Semantic Judge violations: ${cognitive.semanticJudgeViolations}`);
console.log(`Oracle savings: $${cognitive.oracleSavings}`);
// Audit logs (auth required)
const { logs, pagination, actors } = await metricsClient.getAuditLogs({
resource_type: 'Policy',
start_date: '2026-01-01',
end_date: '2026-01-31',
page: 1,
page_size: 50
});
// Convenience methods for audit logs
const policyLogs = await metricsClient.getLogsByResourceType('Policy');
const userLogs = await metricsClient.getLogsByUser('user-id');
const recentLogs = await metricsClient.getLogsByDateRange(
new Date('2026-01-01'),
new Date('2026-01-31')
);
const searchResults = await metricsClient.searchAuditLogs('budget exceeded');REST Client Types
// Policy types
interface Policy {
id: string;
org_id: string;
name: string;
description: string;
rules: PolicyRule[];
priority: number;
enabled: boolean;
status: 'active' | 'inactive' | 'draft';
created_at: string;
updated_at: string;
}
// Approval types
interface Approval {
id: string;
envelope_id: string;
workflow_id: string;
action_name: string;
input_text: string;
status: 'pending' | 'approved' | 'denied' | 'expired';
requested_at: string;
decided_at?: string;
decided_by?: string;
comment?: string;
}
// Budget types
type BudgetScope = 'GLOBAL' | 'TENANT' | 'WORKFLOW' | 'MODEL';
type BudgetPeriod = 'DAILY' | 'WEEKLY' | 'MONTHLY' | 'QUARTERLY';
type BudgetAction = 'WARN' | 'SOFT_LIMIT' | 'HARD_LIMIT';
type BudgetStatus = 'active' | 'warning' | 'exceeded' | 'disabled';
interface Budget {
id: string;
name: string;
scope: BudgetScope;
scope_id: string | null;
limit_amount: number;
current_spend: number;
period: BudgetPeriod;
action: BudgetAction;
status: BudgetStatus;
percentage: number;
alert_thresholds: number[];
}
// Metrics types
interface PublicMetrics {
lastUpdated: string;
policiesEvaluated24h: number;
avgLatencyMs: number;
budgetAlerts24h: number;
activeTenants: number;
blockedRequests24h: number;
cognitiveLayer: CognitiveLayerMetrics;
}
interface CognitiveLayerMetrics {
semanticJudgeRequests: number;
semanticJudgeViolations: number;
oraclePredictions: number;
oracleSavings: number;
immunePoliciesGenerated: number;
}
type ResourceType = 'User' | 'Policy' | 'Budget' | 'APIKey' | 'Workflow' | 'Envelope' | 'Approval';
interface AuditLogEntry {
id: string;
timestamp: string;
actor_id: string;
actor_email: string;
action: string;
resource_type: ResourceType;
resource_id?: string;
resource_name?: string;
status: 'success' | 'failure';
changes?: Record<string, { old: unknown; new: unknown }>;
}Error Handling for REST Clients
Each REST client has its own error class:
import {
PolicyClient,
PolicyClientError,
ApprovalClient,
ApprovalClientError,
BudgetClient,
BudgetClientError,
MetricsClient,
MetricsClientError
} from '@fulcrum-governance/sdk';
try {
const policy = await policyClient.get('invalid-id');
} catch (error) {
if (error instanceof PolicyClientError) {
console.log(`Error: ${error.message}`);
console.log(`Status: ${error.statusCode}`); // e.g., 404, 401, 500
}
}Browser Support
For browser environments, use the REST clients which work with the standard fetch API:
import { PolicyClient, BudgetClient, MetricsClient } from '@fulcrum-governance/sdk';
// REST clients work in browsers
const policyClient = new PolicyClient({
baseUrl: 'https://your-fulcrum-dashboard.com',
apiKey: 'your-api-key'
});
// For real-time governance (gRPC), use the REST envelope wrapper
// (Coming soon)Documentation
Full documentation: https://docs.fulcrum.dev
Support
- Email: [email protected]
- Documentation: https://docs.fulcrum.dev
- Issues: Contact your account representative
