@browserstack/ai-sdk
v1.0.0-beta.22
Published
BrowserStack AI SDK for Node.js — LLM observability, evaluation, and tracing
Maintainers
Readme
@browserstack/ai-sdk
A TypeScript/NodeJS SDK for AI application observability, testing, and evaluation.
Requires Node.js >= 18.
Installation
npm install @browserstack/ai-sdk@betaQuick Start
import { AISDK } from '@browserstack/ai-sdk';
// Initialize the client
const client = new AISDK({
publicKey: 'your-public-key',
secretKey: 'your-secret-key',
});
// Create a trace
const trace = client.trace({
name: 'user_login_flow',
metadata: {
testSuite: 'authentication_tests',
testFile: 'auth.test.js',
},
tags: ['auth', 'critical'],
});
// Create spans
const loginSpan = trace.span({
name: 'navigate_to_login',
input: { url: '/login' }
});
loginSpan.end({
output: { pageLoaded: true, loadTime: 250 }
});
// Create events
trace.event({
name: 'assertion_check',
metadata: {
assertion: 'Login button should be visible',
passed: true,
expected: 'button visible',
actual: 'button visible'
}
});
// Cleanup
await client.flushAsync();
await client.shutdownAsync();Auto-Instrumentation
Automatically trace LLM calls without code changes:
node --require @browserstack/ai-sdk/instrument app.jsConfiguration
The client can be configured using environment variables or constructor options:
Environment Variables
AISDK_PUBLIC_KEY=your_public_key
AISDK_SECRET_KEY=your_secret_keyMemory and backpressure
The SDK holds trace data in memory between your call and a successful delivery. When ingestion is slow or failing, that held data is bounded by a byte budget — once the budget is reached the SDK sheds the oldest traces rather than growing until the process is killed.
| Variable | Default | What it controls |
| --- | --- | --- |
| AISDK_MAX_HELD_BYTES | 104857600 (100 MB) | Total estimated bytes held across the queue and in-flight requests. The one knob to change if you need a different memory ceiling. |
| AISDK_MAX_QUEUE_SIZE | 1000 | Items held before delivery. An independent cap — whichever binds first wins. |
| AISDK_MAX_SOCKETS | 30 | Connection pool size. |
| AISDK_BATCH_SIZE | 15 | Items per request. |
| AISDK_BATCH_TIMEOUT_MS | 5000 | Longest a partial batch waits before being sent. |
| AISDK_MAX_RETRIES | 3 | Retries after a failed attempt, so 4 total attempts. |
| AISDK_REQUEST_TIMEOUT_MS | 30000 | Per-attempt request timeout. 0 disables it entirely. |
Sizing your container. AISDK_MAX_HELD_BYTES bounds the SDK's tracked payload
bytes, not the process. Expect real RSS of roughly 1.8x the budget — a
sustained-failure load test against the 100 MB default settles flat at ~180 MB.
Budget for at least 2x on top of your application's own footprint.
Half the budget is reserved for in-flight requests and half for the queue, so a brief slowdown is absorbed rather than shed: queued items can still be delivered when the endpoint recovers, while in-flight ones are pinned until their retries finish.
Set plain byte counts. Suffixes are not parsed — AISDK_MAX_HELD_BYTES=100MB
reads as 100 bytes, not 100 megabytes, and 1e6 reads as 1. Values below
64 KB are refused with a [CONFIG_REJECTED] line and the default is used instead.
Span attribute limits
OpenTelemetry defaults to 128 attributes per span, which a request advertising
many tools (or a long agentic loop) can approach. The SDK raises this ceiling
to 10000 by default — a backstop against an unbounded producer, not a
payload guard.
| Variable | What it controls |
| --- | --- |
| OTEL_SPAN_ATTRIBUTE_COUNT_LIMIT | Set to a number to use your own span attribute count limit instead of the SDK's default. |
| OTEL_ATTRIBUTE_COUNT_LIMIT | Same override; OpenTelemetry's general (non-span-specific) variable, read when the one above is unset. |
Reading the logs
Four lines are printed by default, without AISDK_DEBUG, because they mean trace
data is being discarded. Each is rate-limited to one line per minute and carries
suppressed=N for the occurrences it stands for.
| Line | Meaning | What to do |
| --- | --- | --- |
| [BUDGET_SHED] | The byte budget was reached; oldest traces dropped. | Ingestion is not keeping up. Check endpoint health first — raising the budget only delays this. |
| [QUEUE_OVERFLOW] | The item cap was reached. | Raise AISDK_MAX_QUEUE_SIZE, or check endpoint health. |
| [INFLIGHT_CAP] | Dispatch paused because in-flight bytes are at their ceiling. | Normal backpressure. Sustained appearances mean ingestion is degraded. |
| [DROP] | A batch was discarded after exhausting its retries. | Delivery was never confirmed. The data may still have reached the server — X-Batch-Id lets ingestion dedupe a retried batch — so treat this as unconfirmed, not as certain loss. |
Everything else, including per-request diagnostics, requires AISDK_DEBUG=true.
Constructor Options
const client = new AISDK({
publicKey: 'your_public_key',
secretKey: 'your_secret_key',
environment: 'production',
flushAt: 20,
flushInterval: 10000,
});