Skip to main content

10. Node.js / TypeScript SDK

agentid-sdk is the official npm package for AgentID server-side Node.js and TypeScript integrations.

Use it when your application calls OpenAI or another model provider from a server, serverless function, worker, or backend job and you want AgentID to guard the request before model execution and persist audit telemetry after it.

Install

npm install agentid-sdk

For OpenAI wrapper usage:

npm install agentid-sdk openai

For LangChain callback usage:

npm install agentid-sdk openai @langchain/core @langchain/openai

The npm package name is agentid-sdk. In this monorepo, the package source lives in agentid-sdk/; the published README is rendered from agentid-sdk/README.md.

Configure

Create an AI system in the AgentID dashboard and set:

export AGENTID_API_KEY="sk_live_..."
export AGENTID_SYSTEM_ID="00000000-0000-0000-0000-000000000000"
export OPENAI_API_KEY="sk-proj-..."

AGENTID_API_KEY is loaded automatically by new AgentID() unless you pass apiKey explicitly.

Minimal Guard and Log

import { AgentID } from "agentid-sdk";

const agent = new AgentID();
const systemId = process.env.AGENTID_SYSTEM_ID!;

const verdict = await agent.guard({
system_id: systemId,
input: "Summarize this ticket in one sentence.",
model: "gpt-4o-mini",
user_id: "quickstart-user",
});

if (!verdict.allowed) {
throw new Error(`Blocked by AgentID: ${verdict.reason}`);
}

await agent.log({
system_id: systemId,
event_id: verdict.client_event_id,
model: "gpt-4o-mini",
input: "Summarize this ticket in one sentence.",
output: "Summary generated.",
usage: {
prompt_tokens: 33,
completion_tokens: 9,
total_tokens: 42,
},
latency: 1450,
metadata: { agent_role: "support-assistant" },
});

This explicit pattern is best for custom model providers or app architectures that do not use one of the automatic wrappers.

The usage and latency fields are not optional in practice if you expect cost and ROI dashboards to work. Without provider token usage, AgentID can store the Activity row but cannot reliably compute token totals, cost_usd, Total Spend, or projected savings.

OpenAI Wrapper

import OpenAI from "openai";
import { AgentID } from "agentid-sdk";

const agent = new AgentID();
const openai = new OpenAI({ apiKey: process.env.OPENAI_API_KEY! });

const secured = agent.wrapOpenAI(openai, {
system_id: process.env.AGENTID_SYSTEM_ID!,
user_id: "customer-123",
expected_languages: ["en"],
});

const response = await secured.chat.completions.create({
model: "gpt-4o-mini",
messages: [
{ role: "user", content: "What is the capital of the Czech Republic?" },
],
});

console.log(response.choices[0]?.message?.content ?? "");

The wrapper calls /guard before chat.completions.create(...). Denied prompts are blocked before the provider call. Allowed requests are logged through /ingest, with SDK timing finalized through /ingest/finalize.

The wrapper reads token usage from the OpenAI response and forwards it to AgentID completion telemetry when the provider includes it. For custom OpenAI helpers, make sure the actual call uses secured.chat.completions.create(...). Calling the raw openai.chat.completions.create(...) client and then calling agent.log(...) with a masked copy does not protect the model.

Current wrapper scope note: wrapOpenAI() preflight currently derives its guard input from the last user message text plus supported inline attachments on that last user turn. If you need preflight evaluation over the exact assembled multi-turn history today, use an explicit manual guard -> provider -> log flow for that route.

For enterprise rollout, the main remaining risk is coverage drift: another provider helper, unsupported OpenAI surface, or parallel raw client call that never reaches wrapOpenAI(...). Treat those paths as coverage gaps until they use the wrapper or an explicit guard -> provider -> log flow.

LangChain Callback

import {
AgentID,
createAgentIdCorrelationId,
createAgentIdTelemetryContext,
} from "agentid-sdk";
import { AgentIDCallbackHandler } from "agentid-sdk/langchain";
import { ChatOpenAI } from "@langchain/openai";

const agent = new AgentID();
const workflowRunId = createAgentIdCorrelationId();

const callbacks = [
new AgentIDCallbackHandler({
agent,
system_id: process.env.AGENTID_SYSTEM_ID!,
telemetry: createAgentIdTelemetryContext({
workflowRunId,
workflowName: "Support triage",
workflowStepName: "draft_reply",
}),
}),
];

const model = new ChatOpenAI({
model: "gpt-4o-mini",
callbacks,
});

Use the same workflowRunId across tool, delivery, inbox, and LLM steps to show one grouped workflow timeline while preserving each prompt/guard row as its own auditable event.

Masking

SDK-side masking follows the dashboard runtime config by default. When enabled, agentid-sdk masks protected content before /guard, before provider dispatch, and before /ingest.

For chat apps, pass the full message history through the wrapped client or through your explicit guard path. If only the latest input is masked but older messages, assistant output, tool results, or retrieval context remain raw, the model can still repeat those values later.

Treat one provider call as one protected unit of work:

  1. assemble the exact messages array for the model call
  2. protect that array once
  3. run one guard() decision for that model call
  4. send the protected history to the provider

Do not loop over historical messages and call guard() once per prior turn. That pattern creates multiple guard rows for one real LLM invocation and makes the audit trail look duplicated.

Current coverage includes common PII plus high-confidence secret material such as provider keys, bearer tokens, JWTs, password assignments, PEM private keys, Azure connection strings, and SAS tokens.

When to Use a Different Package

Use agentid-vercel-sdk instead when the app already uses Vercel AI SDK generateText() or streamText() and you want to keep that callsite unchanged.

Use the Python SDK when your integration runs in Python.

  • npm: https://www.npmjs.com/package/agentid-sdk
  • source package directory: agentid-sdk/
  • dashboard: https://app.getagentid.com