LangChain Integration

The @signalstack/langchain package provides SignalStackTool andSignalStackToolkit for LangChain and LangGraph agents. Use them with any LLM provider supported by LangChain.

Installation

Code
npm install @signalstack/langchain @langchain/core

# yarn
yarn add @signalstack/langchain @langchain/core

Single tool: SignalStackTool

SignalStackTool exposes all four verification endpoints through a single tool. The agent specifies which verification type to use via the input.

Code
import { SignalStackTool } from "@signalstack/langchain"
import { ChatOpenAI } from "@langchain/openai"
import { AgentExecutor, createToolCallingAgent } from "langchain/agents"
import { pull } from "langchain/hub"

const tool = new SignalStackTool({
  apiKey: process.env.SIGNALSTACK_API_KEY!,
  minTrustScore: 0.7,
})

const llm = new ChatOpenAI({ model: "gpt-4", temperature: 0 })
const prompt = await pull<ChatPromptTemplate>("hwchase17/openai-tools-agent")
const agent = createToolCallingAgent({ llm, tools: [tool], prompt })
const executor = new AgentExecutor({ agent, tools: [tool], verbose: true })

const result = await executor.invoke({
  input: "Verify the company 'Acme Corp' registered in Delaware and tell me its status",
})
// Agent calls verify_business with: { company_name: "Acme Corp", jurisdiction: "us_de" }
// Response: Status: active, Trust score: 0.94

Toolkit: SignalStackToolkit

For finer control, use SignalStackToolkit which registers each endpoint as a separate tool:

Code
import { SignalStackToolkit } from "@signalstack/langchain"
import { ChatAnthropic } from "@langchain/anthropic"
import { createOpenAIToolsAgent, AgentExecutor } from "langchain/agents"

const toolkit = new SignalStackToolkit({
  apiKey: process.env.SIGNALSTACK_API_KEY!,
})

const tools = toolkit.getTools()
// Returns: [verifyClaimTool, verifyBusinessTool, verifyDocumentTool, verifyMediaTool]

const llm = new ChatAnthropic({ model: "claude-3-5-sonnet-20241022" })
const agent = await createOpenAIToolsAgent({ llm, tools, prompt })
const executor = new AgentExecutor({ agent, tools })

const result = await executor.invoke({
  input: "Check if this document is AI-generated: https://example.com/report.pdf",
})
// Agent uses verifyDocumentTool directly

LangGraph integration

Code
import { SignalStackTool } from "@signalstack/langchain"
import { StateGraph, MessagesAnnotation } from "@langchain/langgraph"
import { ToolNode } from "@langchain/langgraph/prebuilt"
import { ChatOpenAI } from "@langchain/openai"

const tool = new SignalStackTool({ apiKey: process.env.SIGNALSTACK_API_KEY! })
const toolNode = new ToolNode([tool])

const llm = new ChatOpenAI({ model: "gpt-4" }).bindTools([tool])

const route = (state: typeof MessagesAnnotation.State) => {
  const lastMsg = state.messages[state.messages.length - 1]
  return lastMsg.tool_calls?.length ? "tools" : "__end__"
}

const graph = new StateGraph(MessagesAnnotation)
  .addNode("agent", async (state) => ({
    messages: [await llm.invoke(state.messages)],
  }))
  .addNode("tools", toolNode)
  .addEdge("__start__", "agent")
  .addConditionalEdges("agent", route)
  .addEdge("tools", "agent")

const app = graph.compile()
const result = await app.invoke({
  messages: [{ role: "user", content: "Is the Eiffel Tower in Berlin?" }],
})

Configuration

OptionTypeDefaultDescription
apiKeystringSIGNALSTACK_API_KEY envAPI key
minTrustScorenumber0.8Minimum acceptable trust score
onThresholdFailstring"raise"Action when below threshold
timeoutnumber30000Timeout in ms
maxRetriesnumber3Max retries
cacheResultsbooleantrueCache verification results in memory

Error handling

Code
import { TrustThresholdError } from "@signalstack/langchain"

try {
  const result = await executor.invoke({ input: "Verify: ..." })
} catch (err) {
  if (err instanceof TrustThresholdError) {
    console.log(`Score ${err.trustScore} below threshold ${err.threshold}`)
    console.log(`Evidence:`, err.evidence)
  }
}