Skip to content

LangChain Integration

Wrap LangChain tools with SOVR.

Tool Wrapper

typescript
import { DynamicStructuredTool } from '@langchain/core/tools';
import { SovrClient } from '@sovr/sdk';
import { z } from 'zod';

const sovr = new SovrClient({
  tenantId: process.env.SOVR_TENANT_ID!,
  apiKey: process.env.SOVR_API_KEY!,
});

function withSovr<T extends z.ZodObject<any>>(
  tool: DynamicStructuredTool<T>
): DynamicStructuredTool<T> {
  const originalFunc = tool.func;
  
  return new DynamicStructuredTool({
    name: tool.name,
    description: tool.description,
    schema: tool.schema,
    func: async (input) => {
      const check = await sovr.gate.check({
        action: tool.name,
        context: input,
      });

      if (check.decision === 'allow') {
        return await originalFunc(input);
      }
      return `Blocked: ${check.reason}`;
    },
  });
}

Usage

typescript
const sendEmailTool = withSovr(
  new DynamicStructuredTool({
    name: 'send_email',
    description: 'Send an email',
    schema: z.object({
      to: z.string(),
      subject: z.string(),
      body: z.string(),
    }),
    func: async ({ to, subject, body }) => {
      await sendEmail(to, subject, body);
      return `Email sent to ${to}`;
    },
  })
);

Agent Setup

typescript
import { ChatOpenAI } from '@langchain/openai';
import { AgentExecutor, createOpenAIFunctionsAgent } from 'langchain/agents';

const llm = new ChatOpenAI({ model: 'gpt-4o' });

const tools = [
  withSovr(sendEmailTool),
  withSovr(transferFundsTool),
];

const agent = await createOpenAIFunctionsAgent({ llm, tools, prompt });
const executor = new AgentExecutor({ agent, tools });

await executor.invoke({ input: 'Send report to team' });

The AI Responsibility Layer