Veto/docs

SDK Reference

Unified API reference with TypeScript and Python implementations for each function.

This page is aligned with the current SDK source in veto-sdk/packages/sdk and veto-sdk/packages/sdk-python.

Use the language tabs on any section. Selection is shared across the page, so switching once updates all function examples.

Installation

npm install veto-sdk
pip install veto
pip install veto[all]

Wrapped execution enforces both:

  • input rules before tool execution
  • output output_rules after tool execution, before returning tool output

Veto.init(options?)

import { Veto } from 'veto-sdk';

const vetoLocal = await Veto.init();
const vetoCloud = await Veto.init({ apiKey: 'veto_...' });
const vetoSelfHosted = await Veto.init({ endpoint: 'https://veto.internal.example.com' });
const vetoWithIdentity = await Veto.init({
  agentId: 'support-agent',
  userId: 'user-123',
  role: 'analyst',
});
from veto import Veto, VetoOptions

veto_local = await Veto.init()
veto_cloud = await Veto.init(VetoOptions(api_key='veto_...'))
veto_self_hosted = await Veto.init(VetoOptions(base_url='https://veto.internal.example.com'))
veto_with_identity = await Veto.init(
    VetoOptions(
        agent_id='support-agent',
        user_id='user-123',
        role='analyst',
    )
)

Common identity options:

  • TypeScript: sessionId, agentId, userId, role
  • Python: session_id, agent_id, user_id, role

These identity values are propagated through ValidationContext and guard/cloud validation context payloads.

veto.validateOutput(toolName, output) / veto.validate_output(tool_name, output)

Run standalone output validation/redaction without executing a wrapped tool.

const result = veto.validateOutput('fetch_account', {
  contact: { email: 'alice@example.com' },
});

if (result.decision === 'block') {
  throw new Error(result.reason);
}

console.log(result.output);

OutputValidationResult fields:

  • decision: 'allow' | 'block'
  • output: transformed output (or null when blocked)
  • reason?: block reason
  • matchedRuleIds: string[]
  • redactions: number
result = veto.validate_output(
    "fetch_account",
    {"contact": {"email": "alice@example.com"}},
)

if result.decision == "block":
    raise RuntimeError(result.reason)

print(result.output)

OutputValidationResult fields:

  • decision: 'allow' | 'block'
  • output: transformed output (or None when blocked)
  • reason: str | None
  • matched_rule_ids: list[str] | None
  • redactions: int

veto.wrap(tools)

const wrappedTools = veto.wrap(tools);
wrapped_tools = veto.wrap(tools)

veto.wrapTool(tool) / veto.wrap_tool(tool)

const safeTool = veto.wrapTool(myTool);
safe_tool = veto.wrap_tool(my_tool)

veto.guard(...)

Run Veto validation as a standalone check without wrapping or executing a tool.

import { Veto, type GuardResult } from 'veto-sdk';

const result: GuardResult = await veto.guard(
  'wire_transfer',
  { amount: 25000 },
  {
    sessionId: 'session-42',
    agentId: 'agent-7',
    userId: 'user-99',
    role: 'admin',
  }
);

if (result.decision === 'require_approval') {
  console.log(result.approvalId);
}

GuardResult fields:

  • decision: 'allow' | 'deny' | 'require_approval'
  • reason?: string
  • ruleId?: string
  • severity?: 'critical' | 'high' | 'medium' | 'low' | 'info'
  • approvalId?: string
from veto import GuardResult

result: GuardResult = await veto.guard(
    "wire_transfer",
    {"amount": 25000},
    session_id="session-42",
    agent_id="agent-7",
    user_id="user-99",
    role="admin",
)

if result.decision == "require_approval":
    print(result.approval_id)

GuardResult fields:

  • decision: 'allow' | 'deny' | 'require_approval'
  • reason: str | None
  • rule_id: str | None
  • severity: 'critical' | 'high' | 'medium' | 'low' | 'info' | None
  • approval_id: str | None

Guard semantics

  • Uses the same internal validation engine as wrapped tool execution.
  • Records guard checks in history.
  • Returns deny/approval outcomes instead of throwing ToolCallDeniedError.
  • In log mode, guard() still returns real policy verdicts (it does not convert denies to allows).
  • Per-call identity overrides are supported (sessionId/agentId/userId/role in TypeScript, session_id/agent_id/user_id/role in Python).

veto.getHistoryStats() / veto.get_history_stats()

const stats = veto.getHistoryStats();
// { totalCalls, allowedCalls, deniedCalls, ... }
stats = veto.get_history_stats()
# {"total_calls": ..., "allowed_calls": ..., "denied_calls": ...}

veto.clearHistory() / veto.clear_history()

veto.clearHistory();
veto.clear_history()

veto.setApprovalPreference(...) / veto.set_approval_preference(...)

veto.setApprovalPreference('read_file', 'approve_all');
veto.setApprovalPreference('delete_database', 'deny_all');
veto.set_approval_preference('read_file', 'approve_all')
veto.set_approval_preference('delete_database', 'deny_all')

veto.getApprovalPreference(...) / veto.get_approval_preference(...)

const pref = veto.getApprovalPreference('read_file');
// 'approve_all' | 'deny_all' | undefined
pref = veto.get_approval_preference('read_file')
# 'approve_all' | 'deny_all' | None

veto.clearApprovalPreferences(...) / veto.clear_approval_preferences(...)

veto.clearApprovalPreferences('read_file');
veto.clearApprovalPreferences();
veto.clear_approval_preferences('read_file')
veto.clear_approval_preferences()

veto.wrapMCPTools(...) (TypeScript only)

const { tools, callTool } = veto.wrapMCPTools(mcpTools, mcpServer);

const result = await callTool({
  name: 'read_file',
  arguments: { path: '/tmp/example.txt' },
});
# Not available in the Python SDK.
# Use veto.wrap(...) / veto.wrap_tool(...) with Python tool objects.

veto.registerTools(...) (TypeScript only)

await veto.registerTools([
  {
    name: 'send_email',
    description: 'Send an email',
    parameters: [
      { name: 'to', type: 'string', required: true },
      { name: 'subject', type: 'string', required: true },
    ],
  },
]);
# Not exposed as a top-level Veto method in Python.
# Python auto-registers signatures when you call veto.wrap(...).

veto.getBudgetStatus() / veto.resetBudget() (TypeScript only)

const budget = veto.getBudgetStatus();
// { spent, limit, remaining, currency } | null

veto.resetBudget();
# Budget tracker APIs are not available in the Python SDK.

ToolCallDeniedError

import { ToolCallDeniedError } from 'veto-sdk';

try {
  await wrappedTool.invoke(args);
} catch (error) {
  if (error instanceof ToolCallDeniedError) {
    console.log(error.toolName);
    console.log(error.reason);
    console.log(error.callId);
  }
}
from veto.core.interceptor import ToolCallDeniedError

try:
    await wrapped_tool.ainvoke(args)
except ToolCallDeniedError as error:
    print(error.tool_name)
    print(error.reason)
    print(error.call_id)

ApprovalTimeoutError

import { ApprovalTimeoutError } from 'veto-sdk';

try {
  await client.pollApproval('apr_abc123', {
    pollInterval: 2000,
    timeout: 300000,
  });
} catch (error) {
  if (error instanceof ApprovalTimeoutError) {
    console.log(error.approvalId);
    console.log(error.timeoutMs);
  }
}
from veto.cloud.client import ApprovalTimeoutError

try:
    await client.poll_approval('apr_abc123')
except ApprovalTimeoutError as error:
    print(error.approval_id)
    print(error.timeout)

BudgetExceededError (TypeScript only)

import { BudgetExceededError } from 'veto-sdk';

try {
  await wrappedTool.invoke(args);
} catch (error) {
  if (error instanceof BudgetExceededError) {
    console.log(error.spent);
    console.log(error.limit);
    console.log(error.remaining);
    console.log(error.toolName);
    console.log(error.toolCost);
  }
}
# BudgetExceededError is not currently exposed by the Python SDK.

VetoCloudClient

import { VetoCloudClient } from 'veto-sdk';

const client = new VetoCloudClient({
  config: {
    apiKey: 'veto_abc123...',
    baseUrl: 'https://api.runveto.com',
    timeout: 30000,
    retries: 2,
    retryDelay: 1000,
  },
  logger,
});
from veto.cloud.client import VetoCloudClient, VetoCloudConfig

client = VetoCloudClient(
    VetoCloudConfig(
        api_key='veto_abc123...',
        base_url='https://api.runveto.com',
        timeout=30000,
        retries=2,
        retry_delay=1000,
    )
)

client.registerTools(...) / client.register_tools(...)

await client.registerTools([
  {
    name: 'send_email',
    description: 'Send an email',
    parameters: [
      { name: 'to', type: 'string', required: true },
      { name: 'subject', type: 'string', required: true },
      { name: 'body', type: 'string', required: true },
    ],
  },
]);
from veto.cloud.types import ToolRegistration, ToolParameter

await client.register_tools([
    ToolRegistration(
        name='send_email',
        description='Send an email',
        parameters=[
            ToolParameter(name='to', type='string', required=True),
            ToolParameter(name='subject', type='string', required=True),
            ToolParameter(name='body', type='string', required=True),
        ],
    )
])

client.validate(...)

const result = await client.validate('send_email', {
  to: 'user@example.com',
  subject: 'Hello',
});
result = await client.validate('send_email', {
    'to': 'user@example.com',
    'subject': 'Hello',
})

client.pollApproval(...) / client.poll_approval(...)

const approval = await client.pollApproval('apr_abc123', {
  pollInterval: 2000,
  timeout: 300000,
});
from veto.cloud.types import ApprovalPollOptions

approval = await client.poll_approval(
    'apr_abc123',
    ApprovalPollOptions(poll_interval=2.0, timeout=300.0)
)

client.fetchPolicy(...) / client.fetch_policy(...)

const policy = await client.fetchPolicy('send_email');
policy = await client.fetch_policy('send_email')

client.logDecision(...) / client.log_decision(...)

client.logDecision({
  tool_name: 'send_email',
  arguments: { to: 'user@example.com' },
  decision: 'allow',
  mode: 'deterministic',
  latency_ms: 2,
  source: 'client',
});
client.log_decision({
    'tool_name': 'send_email',
    'arguments': {'to': 'user@example.com'},
    'decision': 'allow',
    'mode': 'deterministic',
    'latency_ms': 2,
    'source': 'client',
})

client.isToolRegistered(...) / client.is_tool_registered(...)

const isRegistered = client.isToolRegistered('send_email');
is_registered = client.is_tool_registered('send_email')

client.clearRegistrationCache() / client.clear_registration_cache()

client.clearRegistrationCache();
client.clear_registration_cache()

client.close() (Python only)

// VetoCloudClient in TypeScript does not expose close().
await client.close()

For deeper language-specific guides, see TypeScript SDK and Python SDK.