Production-ready Node.js client for the Faramesh Execution Governor API.
npm install @faramesh/sdkOr install from local path:
npm install ../path/to/sdk/nodeimport { configure, submitAction, approveAction } from '@faramesh/sdk';
// Configure SDK (optional - defaults to http://127.0.0.1:8000)
configure({
baseUrl: 'http://localhost:8000',
token: 'your-token', // Optional, can also use FARAMESH_TOKEN env var
});
// Submit an action
const action = await submitAction(
'my-agent',
'http',
'get',
{ url: 'https://example.com' }
);
console.log(`Action ${action.id} status: ${action.status}`);
// If action requires approval
if (action.status === 'pending_approval') {
const approved = await approveAction(
action.id,
action.approval_token!,
'Looks safe'
);
console.log(`Action approved: ${approved.status}`);
}const { configure, submitAction, getAction } = require('@faramesh/sdk');
configure({ baseUrl: 'http://localhost:8000' });
(async () => {
const action = await submitAction('agent', 'http', 'get', { url: 'https://example.com' });
console.log(action);
})();Submit multiple actions at once:
const actions = await submitActions([
{ agent_id: 'agent1', tool: 'http', operation: 'get', params: { url: 'https://example.com' } },
{ agent_id: 'agent2', tool: 'http', operation: 'get', params: { url: 'https://example.org' } },
]);Submit an action and automatically wait for completion:
const action = await submitAndWait(
'my-agent',
'http',
'get',
{ url: 'https://example.com' },
{},
{ autoApprove: true, timeout: 60000 }
);Stream events in real-time:
tailEvents((event) => {
console.log(`Event: ${event.event_type} - ${event.action_id}`);
});Build policies in code:
import { createPolicy, validatePolicy, policyToYaml } from '@faramesh/sdk';
const policy = createPolicy([
{
match: { tool: 'http', op: 'get' },
description: 'Allow HTTP GET',
allow: true,
risk: 'low',
},
]);
const errors = validatePolicy(policy);
const yaml = policyToYaml(policy);Get decisions without creating actions and verify hashes client-side:
import { gateDecide, computeRequestHash, executeIfAllowed, replayDecision } from '@faramesh/sdk';
// Gate decide (decision only, no action created)
const decision = await gateDecide(
'my-agent',
'http',
'get',
{ url: 'https://example.com' }
);
if (decision.outcome === 'EXECUTE') {
console.log('Action would be allowed');
} else if (decision.outcome === 'HALT') {
console.log(`Action would be denied: ${decision.reason_code}`);
}import { computeRequestHash } from '@faramesh/sdk';
const payload = {
agent_id: 'my-agent',
tool: 'http',
operation: 'get',
params: { url: 'https://example.com' },
context: {}
};
// Compute hash locally (matches server's request_hash)
const hash = computeRequestHash(payload);
console.log(`Request hash: ${hash}`);import { executeIfAllowed } from '@faramesh/sdk';
const result = await executeIfAllowed({
agentId: 'my-agent',
tool: 'http',
operation: 'get',
params: { url: 'https://example.com' },
executor: async (tool, op, params, ctx) => {
// Your actual execution logic
return { status: 'done' };
}
});
if (result.executed) {
console.log('Action executed:', result.executionResult);
} else {
console.log('Action blocked:', result.reasonCode);
}import { replayDecision } from '@faramesh/sdk';
// Verify decision is deterministic
const result = await replayDecision({ actionId: 'abc123' });
if (result.success) {
console.log('Decision replay passed!');
} else {
console.log('Mismatches:', result.mismatches);
}Configure the global SDK client.
configure({
baseUrl: 'http://localhost:8000', // Default: http://127.0.0.1:8000
token: 'your-token', // Optional, can use FARAMESH_TOKEN env var
timeoutMs: 30000, // Default: 30000
maxRetries: 3, // Default: 3
retryBackoffFactor: 0.5, // Default: 0.5
});Environment variables:
FARAMESH_BASE_URLorFARA_API_BASE- Base URLFARAMESH_TOKENorFARA_AUTH_TOKEN- Authentication token
Submit an action for governance evaluation.
Submit multiple actions in batch. Returns array of action results (or errors).
Submit an action and wait for completion. Options:
pollInterval- Milliseconds between polls (default: 1000)timeout- Maximum milliseconds to wait (default: 60000)autoApprove- Automatically approve pending actions (default: false)
const action = await submitAction(
'my-agent',
'http',
'get',
{ url: 'https://example.com' },
{ source: 'test' }
);Returns: Promise<Action>
Get an action by ID.
const action = await getAction('12345678-1234-1234-1234-123456789abc');Returns: Promise<Action>
List actions with optional filters.
const actions = await listActions({
limit: 20,
offset: 0,
agent_id: 'my-agent',
tool: 'http',
status: 'pending_approval',
});Returns: Promise<Action[]>
Approve a pending action.
const action = await submitAction('agent', 'shell', 'run', { cmd: 'ls' });
if (action.status === 'pending_approval') {
const approved = await approveAction(
action.id,
action.approval_token!,
'Approved by admin'
);
}Returns: Promise<Action>
Deny a pending action.
const denied = await denyAction(
action.id,
action.approval_token!,
'Too dangerous'
);Returns: Promise<Action>
Start execution of an approved or allowed action.
const action = await submitAction('agent', 'http', 'get', { url: 'https://example.com' });
if (action.status === 'allowed') {
const started = await startAction(action.id);
}Returns: Promise<Action>
Replay an action by creating a new action with the same parameters.
const original = await getAction('123');
const replayed = await replayAction('123');
console.log(`Replayed action: ${replayed.id}`);Returns: Promise<Action>
Wait for an action to complete (succeeded or failed).
const action = await startAction('123');
const final = await waitForCompletion(action.id, 1000, 60000);
console.log(`Final status: ${final.status}`);Parameters:
pollInterval- Milliseconds between polls (default: 1000)timeout- Maximum milliseconds to wait (default: 60000)
Returns: Promise<Action>
Load an action from a YAML or JSON file and submit it.
Stream events via Server-Sent Events (SSE). Calls callback for each event.
// action.yaml
// agent_id: my-agent
// tool: http
// operation: get
// params:
// url: https://example.com
const action = await apply('./action.yaml');Returns: Promise<Action>
allow(actionId, token?, reason?)- Alias forapproveActiondeny(actionId, token?, reason?)- Alias fordenyAction
The SDK provides typed error classes:
import {
FarameshError,
FarameshAuthError,
FarameshNotFoundError,
FarameshPolicyError,
FarameshTimeoutError,
FarameshConnectionError,
FarameshValidationError,
} from '@faramesh/sdk';
try {
const action = await submitAction('agent', 'unknown', 'do', {});
} catch (error) {
if (error instanceof FarameshPolicyError) {
console.error('Action denied by policy:', error.message);
} else if (error instanceof FarameshAuthError) {
console.error('Authentication failed:', error.message);
} else if (error instanceof FarameshNotFoundError) {
console.error('Action not found:', error.message);
} else {
console.error('Error:', error.message);
}
}import {
configure,
submitAction,
approveAction,
startAction,
waitForCompletion,
} from '@faramesh/sdk';
configure({ baseUrl: 'http://localhost:8000' });
async function runAction() {
// Submit action
const action = await submitAction(
'my-agent',
'shell',
'run',
{ cmd: 'ls -la' }
);
console.log(`Action ${action.id} status: ${action.status}`);
// If pending approval, approve it
if (action.status === 'pending_approval') {
const approved = await approveAction(
action.id,
action.approval_token!,
'Approved by automation'
);
console.log(`Action approved: ${approved.id}`);
// Start execution
const started = await startAction(approved.id);
console.log(`Action started: ${started.id}`);
// Wait for completion
const final = await waitForCompletion(started.id);
console.log(`Action completed: ${final.status}`);
}
}
runAction().catch(console.error);Full TypeScript types are included:
import { Action, ActionStatus, ClientConfig } from '@faramesh/sdk';
const action: Action = await getAction('123');
const status: ActionStatus = action.status;cd sdk/node
npm install
npm run buildThe built files will be in dist/.
Source: https://github.com/faramesh/faramesh-node-sdk
Apache 2.0