Collector SDK · Node.js / TypeScript

@dobbyai/collector

Capture telemetry from any Node.js / TypeScript AI agent and stream it to Dobby for governance, compliance, and observability.

View on npm v0.4.0 LIVE · MIT · 0 deps · Node 18+

What this gives you

Every agent run captured

Run lifecycle, LLM calls, tool invocations, agent steps — all stream to Dobby in 10-second batches. Visible in /dashboard/workloads/runs within ~5s of completion.

Policy Scanner auto-fires

Each captured run triggers a compliance scan against your org's Policy Templates (SOC 2 / GDPR / HIPAA / EU AI Act / ISO 42001). Verdicts surface in /dashboard/compliance.

tracing_enabled flips to configured

SDK auto-emits W3C traceparent per batch. The Surrounding-mode governance control "tracing_enabled" automatically marks your org as configured after the first run.

Zero runtime dependencies

Base @dobbyai/collector pulls no production deps — uses Node 18+ built-ins (fetch + crypto.randomUUID + node:async_hooks). Framework peer deps are optional, install only what you use.

Install

npm install @dobbyai/collector

Manual API (any framework, recommended starting point)

Works with any agent code — no framework dependency. Verified end-to-end on prod 2026-05-17 with 6/6 telemetry fields green.

import { init, startRun, endRun, span, shutdown } from '@dobbyai/collector';

init({
  apiKey: process.env.DOBBY_API_KEY!,        // dsdk_* token from the wizard
  connectorId: process.env.DOBBY_CONNECTOR_ID!, // wc_* connector id
  agentAnchor: { agentKey: 'kyc-decisioner' },  // or DOBBY_AGENT_KEY — see below
});

const run = startRun({
  name: 'weekly_report',
  inputs: { week: '2026-W19' },
});

const docs = await span('retrieval', { kind: 'tool', inputs: { q: 'sales' } }, async () => {
  return await retriever.invoke('sales');
});

const summary = await span('summarize', { kind: 'llm' }, async () => {
  return await llm.invoke(docs);
});

endRun(run, { outputs: { summary }, status: 'success' });
await shutdown(); // forces final flush

Agent identity (attestation)

Declare a stable agentKey — in code via agentAnchor, or with the DOBBY_AGENT_KEY environment variable. It is a name you choose and keep the same across deploys, not a secret and not an ID Dobby issues you. It is what lets Dobby resolve every run of this agent — across replicas and restarts — to one canonical entry in your org-wide Agent Register.

# Equivalent to passing agentAnchor: {...} to init()
export DOBBY_AGENT_KEY=kyc-decisioner   # stable name for THIS agent
export DOBBY_AGENT_VERSION=2.3.1        # optional — recorded, never a merge key
export DOBBY_ENV=prod                   # optional
export DOBBY_AGENT_OWNER=risk-team      # optional

Without a declared key, runs are still fully collected, governed and scanned — but their identity is recorded as unverifiable, the agent gets no Agent Register entry, and it is reported as unattributed in the Agent Identity & Coverage section of an evidence pack. Dobby never infers a key for you: an inferred identity is an unprovable claim in an audit, so Dobby reports unverifiable rather than a false attestation.

Framework auto-instrumentation

Each handler is a subpath export — install only the peer dep for the framework you use. Base @dobbyai/collector pulls NO framework deps.

LangChain.js

Pass DobbyLangChainCallbackHandler to your AgentExecutor.invoke() — every chain.start/end, llm.start/end, tool.start/end, agent.step automatically emits a Dobby event. One workload_run per .invoke() call.

npm install @langchain/core
import { init } from '@dobbyai/collector';
import { DobbyLangChainCallbackHandler } from '@dobbyai/collector/langchain';

init({ framework: 'langchain' });
const handler = new DobbyLangChainCallbackHandler();

// Pass to .invoke() / .stream() — every LangChain callback emits a Dobby event
const result = await agent.invoke(
  { input: 'What is the population of Reykjavik?' },
  { callbacks: [handler] },
);

Mastra

wrapMastraAgent returns a Proxy that intercepts .generate() and .stream() calls. Same shape as the original Agent — no other code changes. Tool calls land as nested spans.

npm install @mastra/core
import { init } from '@dobbyai/collector';
import { wrapMastraAgent } from '@dobbyai/collector/mastra';
import { Agent } from '@mastra/core';

init({ framework: 'mastra' });

const agent = wrapMastraAgent(
  new Agent({ /* ... */ }),
  { agentName: 'research-bot' },
);

// Same shape as the original Agent — Proxy intercepts .generate() / .stream()
const result = await agent.generate('What is the weather?');

Vercel AI SDK

trackVercelAiCall wraps generateText / generateObject Promises. vercelAiCallbacks returns { onStepFinish, onFinish } to spread into streamText. Tool calls + step events captured per call.

npm install ai @ai-sdk/openai
import { trackVercelAiCall, vercelAiCallbacks } from '@dobbyai/collector/vercel-ai';
import { generateText, streamText } from 'ai';
import { openai } from '@ai-sdk/openai';

init({ framework: 'vercel-ai' });

// Non-streaming
const result = await trackVercelAiCall(
  'weekly_summary',
  { inputs: { topic: 'AI safety' } },
  () => generateText({ model: openai('gpt-4o-mini'), prompt: '...', tools: {/*...*/} }),
);

// Streaming
const cbs = vercelAiCallbacks({ agentName: 'live_chat' });
const stream = streamText({
  model: openai('gpt-4o-mini'),
  prompt: '...',
  ...cbs,
});

Ready to onboard a customer?

Use the step-by-step walkthrough — covers credential generation, framework-specific snippets, troubleshooting, and known gotchas. ~10–15 minutes end-to-end.

Walkthrough doc

Content capture (on by default)

Unlike Dobby’s OTLP connectors (Claude Code, OpenClaw), the Collector SDK captures content by default: run inputs and outputs, per-call LLM prompt and completion text, and tool arguments / outputs travel inside the events your instrumentation emits, and Dobby stores them with the run — so compliance scans can inspect real evidence out of the box. What lands is what your code sends; you control it client-side:

  • track('search_db', { kind: 'tool', captureArgs: false, captureReturn: false }, searchDb) — skip a tool’s arguments or return value (both default to true).
  • span / startRun / endRun store exactly the inputs / outputs you pass — omit a field and it never leaves your process.

If a compliance scan reports unverifiable and its evidence gap names a missing prompt, tool arguments, or final output, the run reached Dobby without that content — pass inputs / outputs on your runs, keep captureArgs / captureReturn on, or use a framework handler (they capture LLM and tool content automatically). The connector-level capture_content toggle gates Dobby’s OTLP connectors only — it does not change what this SDK’s ingest stores.

Before you rely on it. Content capture means proprietary text and any PII your agents handle leave your process and are stored with your runs. Secrets (API keys, tokens) are masked server-side on ingest, but that is secrets-only — not full PII scrubbing. Use the capture* flags and trim your inputs / outputs for fields that must never leave.

Related

Node Collector | Dobby AI Docs