Vaanieval
Node.js SDK

Overview

Installing and configuring the Vaanieval Node.js SDK — options, defaults, automatic fetch instrumentation and the upload API.

@vaanieal/observer is a zero-dependency, pure-ESM package that records voice-agent calls to a local session package and uploads them after the call.

Source installs and hosted beta

The repositories are public and support anonymous Git access. These guides install the SDKs from public Git. Anonymous registry checks on 20 September 2026 returned HTTP 404 for npm @vaanieal/observer and PyPI vaanieval-observer; no release was found under those names. Source availability does not mean the hosted service is ready for public launch: new public workspaces remain closed.

The quickstarts pin published Python 0.5.7b1 and Node 0.1.1-beta.1 source previews. Both installed previews have uploaded synthetic calls to the isolated hosted development environment. Git/build tooling and explicit revision upgrades are required; this is not registry publication or production-readiness certification.

For setup help, email shubham@vaanieval.com or book a call — a short conversation about your use case tells us whether Vaanieval fits, and helps identify the setup that matches your stack.

Install

npm install github:shubhamofbce/vaanieval-observer-nodejs-sdk

Requires Node.js 20 or newer. The package is ESM-only and uses only Node built-ins — node:async_hooks, node:fs/promises, node:crypto, node:perf_hooks. Nothing else enters your dependency tree.

package.json
{
  "type": "module"
}

Pin a commit or tag in production (github:shubhamofbce/vaanieval-observer-nodejs-sdk#v0.1.0). Installing from a moving branch means a redeploy can change your instrumentation without a version bump.

Constructing the observer

import { VaaniObserver } from '@vaanieal/observer';

const vaani = new VaaniObserver({
  endpoint: 'http://localhost:8000',
  apiKey: 'local-dev',
  spoolDirectory: './.vaani-spool',
  capture: { audio: true, httpBodies: false },
  instrumentations: { fetch: true, websocket: true },
  endpoints: [
    { id: 'stt', type: 'stt', url: 'wss://api.deepgram.com/v1/listen' },
    { id: 'llm', type: 'llm', url: 'https://api.openai.com/v1' },
    { id: 'tts', type: 'tts', url: 'https://api.elevenlabs.io' },
  ],
  upload: { retries: 3 },
  strict: false,
});

Prop

Type

Constructing the observer patches global fetch immediately. It performs no network I/O. Construct it once at process start.

Because fetch is a global, constructing more than one observer in a process stacks patches. Create exactly one and share it.

Lifecycle

Start a session per call

const session = vaani.startSession({ agentId: 'support-bot', metadata: { env: 'prod' } });

End the session

const finalized = await session.end({ outcome: 'completed' });
console.log(finalized.directory, finalized.sessionId);

Closes open spans, composes stereo audio, writes manifest.json last.

Upload

await vaani.uploadPackage(finalized);

Requires endpoint and apiKey — it throws if either is missing. If you skip this, the package simply stays on disk.

Flush at shutdown

process.on('SIGTERM', async () => {
  await vaani.flush();
  process.exit(0);
});

Finalizes every open session. Finalization errors reject, matching Promise.all semantics — a package that could not be written is visible, not swallowed.

Observer API

MethodPurpose
startSession(input)Open a session (sessionId, agentId, metadata)
flush()Finalize all open sessions
run(session, fn)Install ambient context
runWithEndpoint(session, endpointId, fn, turnId)Force an endpoint rule
runWithTurn(session, turnId, fn)Tag ambient work with a turn
currentContext()Read the ambient context
classifyUrl(url)Which endpoint rule a URL matches
observeWebSocket(socket, options)Observe a socket; returns { detach }
uploadPackage(finalized)Upload a written package

Automatic fetch instrumentation

A patched fetch is recorded only when there is an ambient session and the URL matches one of your endpoint rules:

await session.run(async () => {
  await fetch('https://api.openai.com/v1/chat/completions', { method: 'POST', body });
});

Everything else passes through untouched — your database, your feature flag service, your own APIs.

Streaming response bodies are never drained to capture them. Reading a stream to inspect it would hold back the first token, which is exactly the latency this SDK exists to measure. httpBodies: true captures non-streaming bodies only.

Failure behaviour

With strict: false (the default), instrumentation errors are swallowed. Recording problems surface as capture_status counters in the manifest and as the unverifiable class in the dashboard. Set strict: true in staging so those failures throw.

Spool directories are not removed after a successful upload. Add a cleanup sweep of .vaani-spool to your deployment, or audio will accumulate on your agent hosts indefinitely.

Next

On this page