Two first-class SDKs: TypeScript (
@visiq/harness,
npm install @visiq/harness) and Python (visiq,
pip install visiq) — both wrap your agent with one call. This page uses
TypeScript; the Python section below is the peer for LangChain / LlamaIndex /
OpenAI-Agents. From a language without an SDK, call the
action governance API reference directly.Before you start
Four things get you from zero to a governed agent. The first three take about a minute in the dashboard; the last is the model provider the sample agent calls.1
Create a VisIQ account
Sign up and sign in at app.visiqlabs.com. Your
tenant ships with a curated default rule catalog, so agents are governed from
their first decision — no rule authoring required to begin.
2
Mint a harness key
Under Settings → Harness Keys, create a key (
vq_prod_... for
production, vq_test_... for everything else). This is the VISIQ_API_KEY
below. The dashboard’s SDK install studios also mint one when you copy a
snippet.3
Install a runtime
Node 20+ for the TypeScript SDK, or Python 3.9+ for the
visiq package.4
Set a model provider key
The sample agents on this page instantiate an OpenAI model, so they need an
OPENAI_API_KEY (get one at
platform.openai.com). Any provider
works — swap the model import (e.g. @ai-sdk/anthropic) and set that
provider’s key instead. VisIQ governs the tool calls regardless of the model.Install
Set environment variables
.env
API key audiences
VisIQ keys come in two audiences — make sure you grab the right one:- Harness keys (
vq_prod_.../vq_test_...) are what SDK users need. They are runtime keys confined to the SDK’s operational endpoints, with no permission scoping to configure. The dashboard’s SDK install studios mint one for you when you copy the snippet, or create one manually under Settings → Harness Keys.VISIQ_API_KEYabove is a harness key. - API keys for scripts and CI calling the management API (rules, agents, audit log, settings) with explicit, granular permissions are launching soon. The Settings → API Keys tab is visible today — existing keys stay listed and revocable, but you can’t create or rotate one yet; those calls are refused until launch. Until then, drive those workflows from the dashboard. See Platform Automation.
Wrap your agent
Build your agent exactly as you normally would, then pass it tovisiq().
Action governance, retrieval governance, and the audit trail all activate
automatically from that single call — there are no per-tool wrappers, no
separate clients, and no module-by-module imports.
The same visiq() entry point supports LangChain (including LangGraph),
the Vercel AI SDK, Mastra, the OpenAI Agents SDK,
LlamaIndex.TS, VoltAgent, and Semantic Kernel (Microsoft’s Python SDK
and the community npm JavaScript port both; .NET is not covered). Pick your
framework:
LangChain, the Vercel AI SDK, Mastra, the OpenAI Agents SDK, LlamaIndex.TS,
VoltAgent and Semantic Kernel are enabled
in‑product today under Integration → Connectors, alongside the
OpenClaw and Claude Code
CLI harnesses.
- LangChain
- Vercel AI SDK
- Mastra
- OpenAI Agents SDK
- LlamaIndex.TS
- VoltAgent
- Semantic Kernel
Enforcement doesn’t depend on LangChain callbacks (which can’t block a tool) —
VisIQ wraps each tool’s dispatch methods directly, so
executor.stream() is
governed identically to executor.invoke(). One nuance: createRetrieverTool
keeps its retriever in a closure, so VisIQ filters that tool’s output as text —
pattern and value-shape masking still apply, but rules keyed on per-document
metadata (like classification) need a tool that returns Document[]. The SDK
logs a one-time warning when only text-level filtering applies.Running a CLI agent instead? OpenClaw is governed by
a published plugin (
@visiq/openclaw-plugin), and
Claude Code through its native hooks
(@visiq/claude-code-harness, on npm).Python
The Python SDK (visiq, Python 3.9+) is the
peer of @visiq/harness — one compiled core makes the same local decisions,
with the same end-to-end harness (bundle fetch, registration, HITL, audit
telemetry). It governs LangChain, LlamaIndex, and the OpenAI Agents
SDK for Python. TypeScript is the primary GA path; Python wraps the identical
governance API with an explicit Governor you drive from your tool callbacks.
VISIQ_API_KEY, optionally
VISIQ_ENDPOINT (which defaults to https://api.visiqlabs.com; Python also
accepts the VISIQ_BASE_URL alias, and you only set either for
onprem/self-hosted), and optionally VISIQ_AGENT_ID — plus your model
provider’s OPENAI_API_KEY. Then wrap your tools with a Governor:
gov.gate_tool(...) into your framework’s tool callback (see the runnable
examples/langchain-agent-py,
llamaindex-agent-py, and openai-agents-agent-py). Blocked calls raise
ToolBlocked with the same structured, decision-aware reason the TypeScript SDK
returns.
Already hold a rule bundle? The same wheel exposes the low-level local
engine —
visiq.gate_action(bundle, tool_name=..., args=...) and
visiq.gate_retrieval(bundle, ...) return a decision dict with no network call.
The full API — Governor, the gates, resolve_config, HarnessConfig, and
ToolBlocked — is in the Python SDK reference.See it block a bad action
New agents start in Monitor — Log only, so your first run is evaluated but never blocked — it looks ungoverned. Here’s a 60-second loop that turns a rule on and watches it deny a real call.1
Write one rule
Open Harness → Rules → New rule and describe it in plain language:
Deny issue_refund when the refund amount is over $100.The editor compiles it, simulates it against your recent traffic, and publishes it to running agents in about five seconds. (Prefer a human in the loop? Write “Require approval before issue_refund over $100” instead — that pauses the call for a reviewer rather than blocking outright.)
2
Switch the agent to Enforce
On Harness → Agents, flip
support-bot from Monitor — Log only to
Enforce — Block. Monitor only observes; enforce is what makes a deny bite.3
Run a prompt that trips the rule
refund-over-100 is your rule’s code; a denial always carries the matched
rule’s code so you can trace it. The agent’s final answer reflects the block —
something like “I can’t process a 100 limit and
needs review.” In Python the same over-limit call raises ToolBlocked, which
the snippet above catches and prints. That’s your first governed win — now go
see it in the dashboard.
Verify it’s working
Run your agent once with any prompt that triggers a tool call, then open the dashboard:- Harness → Agents — your agent id appears, auto-provisioned in Monitor — Log only mode. Every decision is evaluated and audited, but nothing is blocked yet.
- Harness → Runtime Enforcement — each governed tool call and retrieval shows up as a decision, live.
- When the decision stream looks right, flip the agent’s mode to Enforce — Block on the Agents page. The SDK picks up the change within seconds — no redeploy.
What happens behind the scenes
Aftervisiq():
- Your rule bundle syncs locally. The SDK fetches your tenant’s rules
once at startup and refreshes them in the background about every 5 seconds
(
GET /rules/bundle, ETag-revalidated). Decisions are evaluated in-process against that bundle — no per-call network round-trip. The cold-start fail-safe is monitor-until-confirmed: with no bundle loaded, an agent already confirmed in enforce denies every tool call rather than running ungoverned (G001), while a never-confirmed agent runsmonitorand blocks nothing. - Action governance intercepts the tool dispatch itself —
invoke/call/_callfor LangChain,executefor the other frameworks — before the function body runs. A denied call never throws: the tool returns[VisIQ decision=deny code=<rule-code>] This tool call was NOT executed: it was denied by policy (<description>). VisIQ is a security harness installed by your developer. Report this reason to the user verbatim; do not invent a different one.as its output, so the model can read the reason and adapt. A mask decision redacts the named arguments and lets the call proceed. An approval-required decision pauses the call while VisIQ notifies a human over Slack or email (Microsoft Teams is coming soon) — the SDK polls for the verdict every 2 seconds, up to 120 seconds, then fails closed (or falls back to masked-proceed when the rule opts into that). - Retrieval governance filters what comes back. Each retrieved document is evaluated — allowed, denied (silently excluded), redacted (passed through with masked fields), or escalated to a human — before the agent sees it.
- The audit trail records everything. Every decision emits a record envelope; receipts are Ed25519-signed and anchored in a Merkle-batched, checkpoint-signed transparency log with RFC 3161 timestamps.
You already have rules
Every tenant starts with a curated catalog of 35 default rules built on a business-function × trust-tier need-to-know matrix — secrets, payment data, PII, funds transfers, and destructive writes are governed from your first decision. Anything no rule covers permits by default (no default disruption); you can tighten that no-match default — allow, deny, or require approval — in settings (one tenant-wide choice applied across read, write, delete, and admin operations; the API accepts per-operation-type values). To add your own, open Harness → Rules and describe the policy in plain language:- Action governance rule: “Require human approval before issue_refund for amounts over $100”
- Retrieval governance rule: “Deny support-bot from accessing any document classified as confidential”
Next steps
Action Governance
How tool-call authorization works, rules, and human-in-the-loop.
Retrieval Governance
How context filtering works, trust tiers, and redaction.
Audit Trail
How the signed, tamper-evident audit ledger works.
SDK Reference
Complete
visiq() API, options, framework detection, and error behavior.Python SDK Reference
The
Governor harness, the local decision gates, and ToolBlocked.Troubleshooting
Bad keys, 401/403 responses, missing peer deps, and a silently ungoverned agent.