@fulcrum-governance/sdk
v0.1.1
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;
}Browser Support
For browser environments, use the REST client:
import { FulcrumRestClient } from '@fulcrum-governance/sdk/rest';
const client = new FulcrumRestClient({
baseUrl: 'https://api.fulcrum.dev',
apiKey: 'your-api-key'
});
// Same API as gRPC client
const envelope = client.envelope({ workflowId: 'browser-agent' });Documentation
Full documentation: https://docs.fulcrum.dev
Support
- Email: [email protected]
- Documentation: https://docs.fulcrum.dev
- Issues: Contact your account representative
