New:Socket for Asana Is Now Available.Learn more
Sign In

@decionis/langchain

Package Overview
Dependencies
Maintainers
1
Versions
2
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

@decionis/langchain

Gate any LangChain.js tool or LangGraph.js node on a signed Decionis Decision Dossier.

latest
Source
npmnpm
Version
0.1.1
Version published
Maintainers
1
Created
Source

@decionis/langchain

Gate any LangChain.js tool call or LangGraph.js node on a signed Decionis Decision Dossier. The agent picks the tool; Decionis decides whether the call is allowed to fire — and records every verdict as a verifiable proof artifact.

npm install @decionis/langchain @decionis/sdk @langchain/core

Mirrors decionis-langchain for Python: same shadow → enforce rollout, same ?source=langchain_agent verify-URL attribution, same per-tool short-circuit semantics.

Why

LangChain agents can be jailbroken, prompt-injected, or hallucinated into firing tools that move money, change pricing, send refunds, or delete data. Wrapping the tool with Decionis means:

  • Every tool invocation gets a signed Decision Dossier — the policy verdict (APPROVE / REJECT / REVIEW / ESCALATE), the agent identity, the call arguments, and a public verify URL.
  • Blocked calls short-circuit before the inner tool runs — the LLM sees a structured refusal (DecionisGateRefusal) carrying the dossier id; the caller's audit log keeps the proof.
  • Shadow mode records verdicts without blocking, so a team can roll out policy gradually and review the would-have-rejected rate before enforcing.

Quick start — wrap a LangChain.js tool

import { createDecionisNodeSdk } from "@decionis/sdk";
import { DecionisGateTool } from "@decionis/langchain";
import { DynamicStructuredTool } from "@langchain/core/tools";
import { z } from "zod";

const sendRefund = new DynamicStructuredTool({
  name: "send_refund",
  description: "Issue a refund. Idempotent on customer_id + amount + day.",
  schema: z.object({ customer_id: z.string(), amount_usd: z.number() }),
  func: async ({ customer_id, amount_usd }) => "refund_id-abc",
});

const decionis = createDecionisNodeSdk({
  baseUrl: "https://api.decionis.com",
  apiKey: process.env.DECIONIS_API_KEY!,
});

const gatedRefund = DecionisGateTool.wrap({
  innerTool: sendRefund,
  client: decionis,
  orgId: process.env.DECIONIS_ORG_ID!,
  decisionType: "refund_execution",
  siteBaseUrl: "https://decionis.com",
});

await agent.bindTools([gatedRefund]);

When the LLM picks send_refund, Decionis evaluates first. On APPROVE the inner tool runs and the result is returned. On REJECT / REVIEW / ESCALATE (configurable) the wrapper throws DecionisGateRefusal carrying the dossier id, reason codes, and a public verify URL the LLM can read and the operator can forward.

Quick start — LangGraph.js node

import { StateGraph, END } from "@langchain/langgraph";
import { decionisGateNode } from "@decionis/langchain";

const graph = new StateGraph<MyState>({
  /* channels */
});
graph.addNode("plan", planNode);
graph.addNode(
  "gate",
  decionisGateNode({
    client: decionis,
    orgId: process.env.DECIONIS_ORG_ID!,
    decisionType: "refund_execution",
    siteBaseUrl: "https://decionis.com",
    extractCall: (state) => ({
      toolName: state.proposedTool as string,
      toolArgs: state.proposedArgs as Record<string, unknown>,
    }),
  }),
);
graph.addNode("execute", executeNode);
graph.addNode("refuse", refuseNode);

graph.addEdge("plan", "gate");
graph.addConditionalEdges("gate", (s) => (s.decionis as { outcome: string }).outcome, {
  allowed: "execute",
  blocked: "refuse",
});
graph.addEdge("execute", END);
graph.addEdge("refuse", END);

The node writes a JSON-serializable record under state.decionis so the graph stays checkpointable and the conditional edge can branch on allowed or blocked.

Shadow-mode rollout

Same pattern as the Python wrapper and the GitHub Action: ship in shadow first, review the verdict distribution, then flip to enforce.

The end-to-end PLG funnel — pick a surface → install in shadow → watch verdicts → flip — is walked at decionis.com/shadow-mode?surface=langchain_js.

DecionisGateTool.wrap({
  innerTool: sendRefund,
  client: decionis,
  orgId,
  decisionType: "refund_execution",
  shadowMode: true, // ← every verdict recorded; inner tool always runs
});

In shadow mode the gate never throws — even on REJECT — so existing agent behaviour is unchanged. Verdicts still flow into the dossier ledger so the rollout team can grade policy fit before enforcing.

Tunables

OptionDefaultPurpose
clientrequiredDecionisDecisionExecutor from createDecionisNodeSdk(...).
orgIdrequiredDecionis org id (UUID).
decisionTyperequiredCanonical decision type — usually the workflow key (e.g. refund_execution).
workflowKeydecisionTypeOverride when the workflow key needs to differ from the decision type.
blockOutcomes["REJECT","REVIEW","ESCALATE"]Outcomes that short-circuit the wrapper. Pass ["REJECT"] to let review verdicts through with the dossier recorded.
shadowModefalseRecord verdicts but never throw / never route to blocked.
siteBaseUrlundefinedBase URL used to build a public verify URL (/verify/decision-dossiers/<id>?source=langchain_agent&sig=<dossier_sha256>).
actor{ type: "ai_agent", framework: "langchain_js" }Extra actor metadata (model, session id, user id) merged into the dossier context.
onDecisionundefinedObserver callback (GateResult) => void. Exceptions inside it never break the gate.

Honesty notes

  • shadowMode: true is the only switch that lets the inner tool run on a blocking verdict; the default never silently passes a REJECT. Locked by tests.
  • DecionisGateRefusal.verifyUrl is the same artifact link Slack / Teams / LinkedIn unfurl with the OG card from /api/og/verify/[id]. Forward it to a reviewer when you want the proof one click away.
  • The wrapper preserves the inner tool's name, description, and args schema unchanged so the LLM's tool selection behaviour does not drift.
  • The observer callback's exceptions are swallowed so telemetry can never take down policy enforcement.

Compatibility

  • Node ≥ 20
  • @decionis/sdk (workspace)
  • @langchain/core ≥ 0.3 (peer)
  • @langchain/langgraph is not required to use decionisGateNode — the factory returns a plain state => Promise<state> callable, so LangGraph stays an optional runtime dependency.

Keywords

decionis

FAQs

Package last updated on 15 Aug 2026

Related posts