new Cisora({ apiKey, agentName, ... })
Constructs a client. Call once at agent startup, ideally at module load.
const cisora = new Cisora({
apiKey: process.env.CISORA_API_KEY!,
agentName: 'customer-support-bot',
baseUrl: 'https://cisora.io', // optional
failOpen: true, // default — never block your agent
enabled: true, // set false to disable in tests
});cisora.check({ action_type, tool_name, metadata })
Synchronous policy decision. THIS is the unique thing Cisora gives you — block actions BEFORE they execute, not after the audit.
const { decision, reason } = await cisora.check({
action_type: 'tool_call',
tool_name: 'database_write',
metadata: { table: 'users', field: 'email' }
});
if (decision !== 'allow') {
throw new Error(`Cisora ${decision}: ${reason}`);
}
// Cisora just prevented a PII leak before it shipped.cisora.tool(name, fn, opts?)
Wrap any tool call. Cisora captures inputs, outputs, duration, decision — automatically.
const result = await cisora.tool('send_email', async () => {
return resend.emails.send({ from, to, subject, html });
}, { metadata: { recipient: to } });cisora.modelCall(model, fn, opts?)
Wrap any LLM invocation. You keep using your own Anthropic/OpenAI/Bedrock key — Cisora just records the call.
const reply = await cisora.modelCall('claude-sonnet-4-5', () =>
anthropic.messages.create({ model: 'claude-sonnet-4-5', messages })
);cisora.externalApi(name, fn, opts?)
Wrap any third-party API call (Stripe, Slack, your internal services). Same capture as tool/modelCall.
await cisora.externalApi('stripe.charges.create', () =>
stripe.charges.create({ amount, currency, source })
);cisora.flush()
Force-send queued events. Required in short-lived scripts before process exit.
await cisora.flush();
LangChain auto-instrumentation
Using LangChain? Skip the manual wrapping. Drop in one callback handler and every LLM, tool, and chain run inside that run is captured automatically.
import { Cisora } from '@cisora/sdk';
import { CisoraLangChainHandler } from '@cisora/sdk/langchain';
const cisora = new Cisora({ apiKey: process.env.CISORA_API_KEY!, agentName: 'support-bot' });
const handler = new CisoraLangChainHandler(cisora);
// One callback. Captures every LLM call, every tool call, every chain run.
const result = await chain.invoke(input, { callbacks: [handler] });Works with @langchain/core, langchain, @langchain/anthropic, @langchain/openai, LangGraph, and any framework that accepts LangChain callbacks. @langchain/core is an optional peer dependency — only loaded if you have it installed.
Python SDK
Identical surface, idiomatic Python (context managers instead of callbacks).
from cisora import Cisora
cisora = Cisora(api_key=os.environ["CISORA_API_KEY"],
agent_name="customer-support-bot")
# check() returns the same shape
decision = cisora.check(action_type="tool_call", tool_name="db_write")
# wrap with context managers
with cisora.tool("send_email", metadata={"to": email}) as call:
result = send_email(...)
call.outputs = resultFull source: packages/sdk-ts · packages/sdk-py