npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

@sandboxaq/flintai-sdk-ts

v0.3.1

Published

Lightweight SDK for routing AI agent LLM traffic through a guardrails proxy

Readme

FlintAI SDK (TypeScript)

Lightweight SDK for routing LLM traffic through a guardrails proxy. Wraps OpenAI, Anthropic, Google GenAI, and LangChain LLM clients, with agent framework plugins for Google ADK.

Features

  • LLM SDK wrapping — route LLM traffic through the FlintAI guardrails proxy with a single flintai.wrap() call. Supports OpenAI, Anthropic, Google GenAI, and LangChain chat models.
  • Agent framework plugins — deeper integration with agent lifecycle hooks for metadata extraction and guardrails routing. Currently supports Google ADK.
  • Plugin system for extensibility

Supported Integrations

Every integration package is an optional peer dependency — none is bundled in the published artifact (which ships only dist/), and each is loaded dynamically at runtime. Install only the ones you use.

| Integration | Category | Peer package | Supported version | Routing | |---|---|---|---|---| | OpenAI SDK | LLM SDK | openai | ^6.41.0 (≥6.41.0, <8) | wrap() | | Anthropic SDK | LLM SDK | @anthropic-ai/sdk | ^0.100.1 (0.100.1–1.x) | wrap() | | Google GenAI SDK | LLM SDK | @google/genai | ^2.8.0 (≥2.8.0, <4) | wrap() | | LangChain (ChatOpenAI) | LLM SDK | @langchain/openai | ^1.4.7 | wrap() | | LangChain (ChatAnthropic) | LLM SDK | @langchain/anthropic | ^1.4.0 | wrap() | | LangChain (ChatGoogleGenerativeAI) | LLM SDK | @langchain/google-genai | ^2.1.31 | wrap() | | Google ADK | Agent Framework | @google/adk | ^1.2.0 | ADKGuardrailsPlugin | | .env loading (optional) | Utility | dotenv | ^17.4.2 | loadDotenv |

For the three LLM SDKs, wrap() also enforces the version at runtime — it rejects a provider SDK below the minimum or above the maximum supported major and throws with an actionable message. The ^ ranges above are the contract expressed in peerDependencies; consumers pick the exact version.

Install

npm install @sandboxaq/flintai-sdk-ts

# With optional peer dependencies
npm install @sandboxaq/flintai-sdk-ts openai          # OpenAI SDK
npm install @sandboxaq/flintai-sdk-ts @anthropic-ai/sdk  # Anthropic SDK
npm install @sandboxaq/flintai-sdk-ts @google/genai   # Google GenAI SDK
npm install @sandboxaq/flintai-sdk-ts @google/adk     # Google ADK (includes GenAI)

The base package has no runtime dependencies — installing @sandboxaq/flintai-sdk-ts alone pulls nothing else. Add only the peer(s) for the providers you use, at a version in the supported range. Because peers are loaded dynamically, a missing peer surfaces only when you actually route through that provider (with a clear "install X" error), not at install time.

Peer auto-installation is intentionally disabled for this repo (autoInstallPeers: false in pnpm-workspace.yaml). The SDK never statically imports a peer, so the dev build, typecheck, and tests do not need them — keeping the optional providers (and their transitive advisories) out of the development lockfile. To exercise the ADK or LangChain code paths locally, install those packages explicitly.

Guardrails

Route all LLM traffic through the FlintAI guardrails proxy. Create your client as usual, then call wrap() — it auto-detects the provider and applies guardrails routing.

OpenAI

import OpenAI from "openai";
import { wrap } from "@sandboxaq/flintai-sdk-ts";

const client = new OpenAI({ apiKey: "your-openai-api-key" });
wrap(client, {
  gatewayUrl: "https://app.flintai.dev",
  apiKey: "your-guardrails-api-key",
  policyId: "your-policy-id",  // optional
});

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

Anthropic

import Anthropic from "@anthropic-ai/sdk";
import { wrap } from "@sandboxaq/flintai-sdk-ts";

const client = new Anthropic({ apiKey: "your-anthropic-api-key" });
wrap(client, {
  gatewayUrl: "https://app.flintai.dev",
  apiKey: "your-guardrails-api-key",
});

const message = await client.messages.create({
  model: "claude-sonnet-4-20250514",
  max_tokens: 1024,
  messages: [{ role: "user", content: "Hello" }],
});

Google GenAI

import { GoogleGenAI } from "@google/genai";
import { wrap } from "@sandboxaq/flintai-sdk-ts";

const client = new GoogleGenAI({ apiKey: "your-gemini-api-key" });
wrap(client, {
  gatewayUrl: "https://app.flintai.dev",
  apiKey: "your-guardrails-api-key",
});

const response = await client.models.generateContent({
  model: "gemini-2.5-flash",
  contents: "Hello",
});

LangChain

Create your LangChain chat model as usual, then call wrap() — it detects the LangChain model, finds the underlying SDK client, and applies guardrails routing:

import { ChatOpenAI } from "@langchain/openai";
import { wrap } from "@sandboxaq/flintai-sdk-ts";

const llm = new ChatOpenAI({ model: "gpt-4", apiKey: "your-openai-api-key" });
wrap(llm, {
  gatewayUrl: "https://app.flintai.dev",
  apiKey: "your-guardrails-api-key",
});

const response = await llm.invoke("Hello");

Works with ChatOpenAI, ChatAnthropic, and ChatGoogleGenerativeAI.

Google ADK

ADK agents lazily create their GenAI client at runtime and use generateContentConfig for per-request routing, so wrap() cannot be used. Use the ADK plugin instead:

import { ADKGuardrailsPlugin } from "@sandboxaq/flintai-sdk-ts/plugins/adk";
import { Agent } from "@google/adk";

const plugin = new ADKGuardrailsPlugin({
  gatewayUrl: "https://app.flintai.dev",
  apiKey: "your-guardrails-api-key",
});

const agent = new Agent({
  model: "gemini-2.5-flash",
  generateContentConfig: plugin.contentConfig,
  beforeModelCallback: plugin.beforeModelCallback,
  onModelErrorCallback: ADKGuardrailsPlugin.onModelError,
});

Passing your own contentConfig: if you supply contentConfig: ... to the plugin, wire plugin.contentConfig (not your original object) into the Agent. The plugin returns a clone with the guardrails httpOptions attached and leaves your object untouched, so passing the original sends traffic straight to the model — and with requireGuardrails enabled by default, beforeModelCallback raises.

beforeModelCallback extracts the ADK session ID and attaches it as an X-Agent-Session-Id header on each guardrails request. onModelErrorCallback converts FlintAI guardrails blocks (403 / keyword match) into an LlmResponse so the agent can handle them gracefully.

Configuration Reference

wrap() and init() accept these guardrails parameters:

| Parameter | Type | Description | |-----------|------|-------------| | gatewayUrl | string | Guardrails proxy URL | | apiKey | string | Your guardrails API key | | policyId | string \| undefined | Guardrails policy ID to apply (optional) | | agentName | string \| undefined | Agent name used as agentId when no explicit agentId is provided | | agentId | string \| undefined | Explicit agent ID (overrides agentName) | | requireGuardrails | boolean \| undefined | When true (default), throws FlintAIGuardrailsError if guardrails config cannot be resolved. Set to false to allow operation without guardrails. | | dangerouslyDisableGuardrails | boolean \| undefined | Explicit, self-documenting opt-out equivalent to requireGuardrails: false. Prefer this so unguarded deployments are greppable. Cannot be combined with requireGuardrails: true. Either opt-out emits a once-per-process SECURITY CONTROL DISABLED console warning so it stays auditable. |

Environment Variables

Instead of passing credentials in code, you can set them as environment variables:

| Environment Variable | Parameter | Description | |---------------------------------|--------------|---------------------------------------------------------------------------------------------------------------| | FLINTAI_GATEWAY_URL | gatewayUrl | Guardrails proxy URL | | FLINTAI_API_KEY | apiKey | Your guardrails API key | | FLINTAI_POLICY_ID | policyId | Guardrails policy ID (optional) | | AGENT_ID | agentId | Agent identifier attached to guardrails requests | | AGENT_NAME | agentName | Agent name attached to guardrails requests | | FLINTAI_ALLOWED_GATEWAY_HOSTS | — | Comma-separated list of allowed gateway hostnames. Default: app.flintai.dev. The * wildcard requires allowInsecureGateway: true (see Security). |

Environment variables are read automatically. A .env file is not read by default — pass loadDotenv: true to load <cwd>/.env, or loadDotenv: "/path/to/.env" to load a specific trusted file (requires dotenv as a peer dependency):

# .env
FLINTAI_GATEWAY_URL=https://app.flintai.dev
FLINTAI_API_KEY=your-guardrails-api-key

Then use FlintAI SDK without passing credentials:

import OpenAI from "openai";
import { wrap } from "@sandboxaq/flintai-sdk-ts";

const client = new OpenAI();
wrap(client, { loadDotenv: true });  // reads env vars + <cwd>/.env

Precedence: Explicit parameters > environment variables.

Multiple provider keys: If multiple provider API keys are set in the environment (OPENAI_API_KEY, ANTHROPIC_API_KEY, GOOGLE_API_KEY), auto-detection will fail. Pass provider explicitly to init() to disambiguate.

How It Works

  1. wrap(client, { gatewayUrl, ... }) auto-detects the provider from the client type, computes the provider-specific path prefix (/openai, /anthropic, /gemini), rewrites the client's base URL, and injects custom headers (X-FlintAI-API-Key, X-Guardrails-Policy-Id)
  2. The FlintAI guardrails proxy intercepts the request, applies policy checks (detectors), and strips the custom headers
  3. The proxy uses its own upstream credentials configured via environment variables to forward requests to the LLM provider

Global state: Each wrap() call updates the global FlintAI SDK client's guardrails config. If you wrap multiple clients with different parameters, each client retains its own headers and base URL, but only the last wrap() call's config is stored globally. For most applications (single provider, shared credentials), this is transparent.

Known Limitations

Private attribute mutation: wrap() redirects traffic by rewriting each client's base URL and injecting the guardrails headers (X-FlintAI-API-Key, X-Guardrails-Policy-Id). For OpenAI and Anthropic this uses the public baseURL property plus the internal _options.defaultHeaders, and for Google the internal apiClient.clientOptions.httpOptions. The internal attributes are not part of the respective SDKs' public API and may change without notice, so pin your SDK versions to the tested ranges:

  • openai >=6.41.0,<7
  • @anthropic-ai/sdk >=0.100.1,<1
  • @google/genai >=2.8.0,<3

wrap() resolves the installed version from each SDK's package.json and emits a console warning if it falls outside the tested range.

Google GenAI URL normalization: The Google GenAI SDK requires a trailing slash on the base URL. FlintAI SDK normalizes this automatically — do not add a trailing slash to gatewayUrl.

Security

Fail-closed by default: init() and wrap() throw FlintAIGuardrailsError when guardrails configuration cannot be resolved. To opt out, pass dangerouslyDisableGuardrails: true (preferred, self-documenting) or requireGuardrails: false. The opt-out is not silent: init(), wrap(), and the ADK plugin emit a SECURITY CONTROL DISABLED console warning (including the resolved agent identifier) — once per process — whenever guardrails are disabled, so unguarded deployments are detectable in logs/telemetry.

Inspect the effective posture: call flintai.status() (or client.guardrailsStatus()) at runtime to get { active, requireGuardrails, provider, agentId, agentName }, where active is true only when traffic is actually routed through the gateway. Returns null before init(). Use this to assert protection rather than trusting the opt-out flag alone.

HTTPS enforcement: Gateway URLs must use https:// for non-loopback hosts. http:// is allowed only for loopback (localhost, 127.0.0.1, ::1) and only when allowInsecureGateway: true is set (with a console warning).

Gateway host allowlist: By default, only app.flintai.dev is allowed as a gateway host. Override with the FLINTAI_ALLOWED_GATEWAY_HOSTS environment variable (comma-separated hostnames).

Loopback and wildcard require an explicit code opt-in: A loopback gatewayUrl and the FLINTAI_ALLOWED_GATEWAY_HOSTS='*' wildcard both let a caller redirect the FlintAI API key, provider credentials, and all prompt/response traffic to an unintended endpoint. Neither can be enabled through the environment or a .env file — you must pass allowInsecureGateway: true to init()/wrap() (intended for local development only). Requesting loopback or * without it throws at config time; using * with it also emits a console warning.

Plugins

Plugins handle events from the FlintAI SDK lifecycle. Extend FlintAIPlugin and override the methods you care about:

import { init, registerPlugin, FlintAIPlugin } from "@sandboxaq/flintai-sdk-ts";

class MyPlugin extends FlintAIPlugin {
  name = "my-plugin";

  onInit(client) {
    console.log(`Plugin initialized with ${client}`);
  }

  onShutdown() {
    console.log("Shutting down");
  }
}

init();
registerPlugin(new MyPlugin());

Plugin Methods

| Method | Called when | |--------|-----------| | onInit(client) | Plugin is registered | | onShutdown() | shutdown() is called |

License

Apache-2.0