Skip to main content

Documentation Index

Fetch the complete documentation index at: https://docs.visiqlabs.com/llms.txt

Use this file to discover all available pages before exploring further.

The @visiq/sdk package exports one function and one type. That is the entire public surface.
import { visiq, type VisiqOptions } from "@visiq/sdk";

visiq(target, options?)

Inject governance into an agentic framework instance. Mutates target in place (monkey-patches invoke() and stream()) and returns the same reference.
function visiq<T extends object>(target: T, options?: VisiqOptions): T;

Behavior

  1. Detects the framework by inspecting target
  2. Installs ALLOW — wraps invoke() and stream() with a callback handler that intercepts handleToolStart before every tool call
  3. Installs RECALL — walks the tools array, finds retrievers, and monkey-patches them to filter documents through policy
  4. Activates RECORD — every ALLOW and RECALL evaluation emits a signed RecordEnvelope
  5. Returns the same target reference — your code is unchanged
Pass each executor to visiq() exactly once. Re-wrapping is a no-op for retrievers (guarded by an internal symbol), but invoke/stream are re-patched on each call.

Framework detection

FrameworkDetectionWhat happens
LangChain AgentExecutortarget.invoke + target.agent + target.tools arrayinvoke()/stream() wrapped; tools array walked for retrievers
LangGraph CompiledGraphtarget.invoke + target.nodes + target.edgesinvoke()/stream() wrapped; retriever walking skipped (nodes, not flat tools)
Anything else throws:
[VisIQ] Cannot detect agentic framework. Pass a LangChain AgentExecutor, LangGraph CompiledGraph, or similar.

Retriever detection

For each tool in target.tools, the harness checks three patterns:
OrderPatternMatch conditionWhat gets patched
1LangChain BaseRetrievertool._getRelevantDocuments is a function_getRelevantDocuments() wrapped; results filtered
2Generic retrievertool.retrieve is a function (no _getRelevantDocuments)retrieve() wrapped and filtered
3Nested retrievertool.retriever is an objectRecurses into tool.retriever and re-applies patterns 1-3
Pattern 3 recurses through .retriever chains, so tool.retriever.retriever._getRelevantDocuments is reachable. An internal Symbol.for("visiq.recall.instrumented") marker prevents re-wrapping.
Use createRetrieverTool from LangChain, not DynamicTool with a vector store in a closure. DynamicTool exposes none of the retriever interfaces, so RECALL will silently skip it.

VisiqOptions

interface VisiqOptions {
  agentId?: string;
  apiKey?: string;
  endpoint?: string;
}
FieldTypeRequiredEnv var fallbackDescription
agentIdstringYes (option or env)VISIQ_AGENT_IDAgent identity for every evaluation
apiKeystringNoVISIQ_API_KEYAPI key from the VisIQ dashboard
endpointstringNoVISIQ_ENDPOINTBackend base URL (default: https://api.visiqlabs.com)
If agentId is not provided via option or env var, visiq() throws:
[VisIQ] agentId is required. Pass it or set VISIQ_AGENT_ID.
There is no mode, failBehavior, or timeoutMs field. Evaluation mode and fail-closed behavior are governed by your rule bundle in the dashboard.

Error behavior

Denied tool calls (ALLOW)

When a tool call is denied, the harness throws synchronously inside the agent’s tool loop:
[VisIQ] Blocked: <reason> (rule: <ruleId>)
In the default AgentExecutor configuration, this aborts the run and surfaces the error to your invoke() caller.

Denied documents (RECALL)

Denied documents are silently excluded from the result list. No error is thrown — suppression is a normal policy outcome, not an exception. If every document is denied, the retriever returns an empty array.

Fail-closed (G001)

Both ALLOW and RECALL fail closed. If the backend is unreachable, tool calls are denied and documents are suppressed. A misconfigured harness never becomes a silent bypass.

@visiq/sdk/record types

Import audit trail types from the subpath export:
import type {
  RecordEnvelope,
  RecordSource,
  RecordDecisionPayload,
  SigningResult,
  ReceiptVerificationInput,
} from "@visiq/sdk/record";
TypeDescription
RecordEnvelopeComplete audit record — source, decision, event, attestation (signature + hash)
RecordSource"allow" | "recall"
RecordDecisionPayloadSigned payload — decision ID, vendor, customer, action, data hash, timestamp
SigningResultEd25519 signature (base64url), public key, SHA-256 payload hash
ReceiptVerificationInputInput shape for verifying a receipt’s integrity
See RECORD for the full envelope structure and verification flow.