Skip to main content

TypeScript / Node.js SDK

The Loopers TypeScript SDK wraps the official OpenAI client with budget checking headers and session tracking built in.

Installation

You can install the SDK using npm or yarn:

npm install @loopers/client
# or
yarn add @loopers/client

Quick Start

import { LoopersOpenAI } from '@loopers/client';

const client = new LoopersOpenAI({
loopersUrl: 'http://localhost:8080',
loopersKey: 'lp-xxx',
providerKey: 'sk-proj-...',
sessionId: 'run-1',
sessionBudget: 5.00,
maxSteps: 20,
});

const response = await client.chat.completions.create({
model: 'gpt-4o',
messages: [{ role: 'user', content: 'Hello Loopers' }],
});

console.log(response.choices[0].message.content);
console.log(`Cost: ${response.loopers_cost.toFixed(4)}`);

Streaming Responses

const stream = await client.chat.completions.create({
model: 'gpt-4o',
messages: [{ role: 'user', content: 'Explain databases' }],
stream: true,
});

for await (const chunk of stream) {
const text = chunk.choices[0]?.delta?.content ?? '';
process.stdout.write(text);
}

LangChain Integration

import { ChatOpenAI } from '@langchain/openai';

const model = new ChatOpenAI({
modelName: 'gpt-4o',
openAIApiKey: 'lp-xxx', // Use your Loopers key here
configuration: {
baseURL: 'http://localhost:8080/openai/v1',
defaultHeaders: {
'X-Loopers-Provider-Key': process.env.OPENAI_API_KEY!,
'X-Loopers-Session-ID': 'run-1',
'X-Loopers-Session-Budget': '2.00',
},
},
});

Policy Denial Handling (onPolicyBlock Callback)

You can pass an onPolicyBlock handler to intercept OPA policy denials and transform them into injectable tool errors without throwing exceptions:

import { LoopersOpenAI, formatAsToolOutput } from '@loopers/client';

const client = new LoopersOpenAI({
loopersUrl: 'http://localhost:8080',
loopersKey: 'lp-xxx',
providerKey: 'sk-proj-...',
sessionId: 'run-1',
onPolicyBlock: (denial, _res) => {
// Format denial into tool failure string for LLM self-correction
const toolError = formatAsToolOutput(denial);
// "Error: tool [outbound_http] blocked. Reason: secret_accessed taint set"

// Return custom mock response or handle gracefully
return new Response(JSON.stringify({ error: toolError }), { status: 200 });
},
});

Parameters Reference

OptionTypeRequiredDescription
loopersUrlstringYesAddress of your Loopers proxy server
loopersKeystringYesYour Loopers key starting with lp
providerKeystringYesYour real AI provider key
sessionIdstringNoUnique session ID for loop detection
sessionBudgetnumberNoSpend limit in USD for this session
maxStepsnumberNoMaximum AI calls allowed in this session
onPolicyBlockfunctionNoCallback invoked on policy blocks for self-correction