View on npm netra-sdk - AI observability SDK for TypeScript/JavaScript applications
Installation
Netra Class
The Netra class is the main entry point for all SDK operations. All methods are static and can be called directly on the class.
init
Initialize the Netra SDK with configuration options. This method is async and waits for all instrumentations to be ready before returning. Call this once at the start of your application, before importing other libraries for best results.
import { Netra , NetraInstruments } from "netra-sdk" ;
await Netra . init ({
appName: "my-ai-app" ,
headers: `x-api-key= ${ process . env . NETRA_API_KEY } ` ,
environment: "production" ,
traceContent: true ,
instruments: new Set ([ NetraInstruments . OPENAI , NetraInstruments . LANGCHAIN ]),
});
Always await the init() call to ensure all instrumentations (like OpenAI, Anthropic, LangGraph) are fully patched before your application starts using them. This is especially important in frameworks like NestJS where modules are loaded after initialization.
Parameters:
Parameter Type Description appNamestring?Name of your application for identification in the dashboard headersstring?Headers for API requests (e.g., x-api-key=your-key) disableBatchboolean?Disable batch processing of spans (default: false) traceContentboolean?Enable tracing of prompt/completion content (default: true) resourceAttributesRecord<string, any>?Additional OpenTelemetry resource attributes environmentstring?Application environment (e.g., “production”, “staging”) instrumentsSet<NetraInstruments>?Set of instrumentations to enable (enables only these) blockInstrumentsSet<NetraInstruments>?Set of instrumentations to disable enableRootSpanboolean?Create a root span wrapping all traces debugModeboolean?Enable debug logging enableScrubbingboolean?Enable PII scrubbing blockedSpansstring[]?Span names to filter out globally (supports wildcards)
Returns: Promise<void>
startSpan
Create a new span for manual tracing. Unlike Python, TypeScript requires explicit end() calls.
import { Netra , SpanType } from "netra-sdk" ;
// Basic usage
const span = Netra . startSpan ( "process-document" );
try {
const result = await processDocument ( doc );
span . setAttribute ( "pages" , result . pageCount );
span . setSuccess ();
} catch ( error ) {
span . setError ( error . message );
throw error ;
} finally {
span . end ();
}
// With span type and attributes
const genSpan = Netra . startSpan ( "generate-response" , { attributes: { model: "gpt-4" }, moduleName: "chat" }, undefined , SpanType . GENERATION );
Parameters:
Parameter Type Description namestringName of the span (required) options.asTypeSpanType?Type of span for categorization options.attributesRecord<string, any>?Initial attributes to set options.moduleNamestring?Module name for organization
Returns: SpanWrapper instance
setSessionId
Set the session ID for the current context. All subsequent spans will be associated with this session.
Netra . setSessionId ( "session-abc123" );
Parameters:
Parameter Type Description sessionIdstringUnique identifier for the session
Returns: void
setUserId
Set the user ID for the current context.
Netra . setUserId ( "user-456" );
Parameters:
Parameter Type Description userIdstringUnique identifier for the user
Returns: void
setTenantId
Set the tenant ID for multi-tenant applications.
Netra . setTenantId ( "tenant-org-789" );
Parameters:
Parameter Type Description tenantIdstringUnique identifier for the tenant
Returns: void
setCustomAttributes
Add custom key-value attributes to the current context.
Netra . setCustomAttributes ({ key: "customer_tier" , value: "premium" });
Netra . setCustomAttributes ({ key: "region" , value: "us-east" });
Parameters:
Parameter Type Description options.keystringAttribute key options.valueanyAttribute value
Returns: void
setCustomEvent
Record a custom event in the current context.
Netra . setCustomEvent ({
event_name: "user_feedback" ,
attributes: {
rating: 5 ,
comment: "Great response!" ,
category: "positive" ,
},
});
Parameters:
Parameter Type Description options.event_namestringName of the event options.attributesRecord<string, any>Event attributes
Returns: void
shutdown
Gracefully shutdown the SDK, flushing any pending spans.
Returns: Promise<void>
SpanWrapper Class
The SpanWrapper class provides methods for enriching spans with additional context. It’s returned by Netra.startSpan() and supports method chaining.
setAttribute
Add a custom attribute to the span.
span . setAttribute ( "query" , userQuery );
span . setAttribute ( "results.count" , results . length );
Parameters:
Parameter Type Description keystringAttribute key valueanyAttribute value
Returns: SpanWrapper (for chaining)
addEvent
Record a timestamped event within the span.
span . addEvent ( "validation-started" );
span . addEvent ( "validation-completed" , { valid: true , errors: 0 });
Parameters:
Parameter Type Description namestringEvent name attributesRecord<string, any>?Event attributes
Returns: SpanWrapper (for chaining)
setPrompt
Set the input prompt for LLM spans.
span . setPrompt ( "Summarize this article: ..." );
Parameters:
Parameter Type Description promptstringThe prompt text
Returns: SpanWrapper (for chaining)
setNegativePrompt
Set the negative prompt (commonly used for image generation).
span . setNegativePrompt ( "blurry, low quality, distorted" );
Parameters:
Parameter Type Description promptstringThe negative prompt text
Returns: SpanWrapper (for chaining)
setModel
Set the model name used in the operation.
span . setModel ( "gpt-4-turbo" );
Parameters:
Parameter Type Description modelstringModel name
Returns: SpanWrapper (for chaining)
setLlmSystem
Set the LLM provider/system name.
span . setLlmSystem ( "openai" );
Parameters:
Parameter Type Description systemstringLLM system name
Returns: SpanWrapper (for chaining)
setUsage
Record token usage and cost metrics.
span . setUsage ([
{
model: "gpt-4" ,
costInUsd: 0.006 ,
usageType: "chat" ,
unitsUsed: 1 ,
},
]);
Parameters:
Parameter Type Description usageDataUsageModel[]List of usage records
Returns: SpanWrapper (for chaining)
setAction
Track actions or tool calls within the span.
span . setAction ([
{
action: "DB" ,
actionType: "INSERT" ,
affectedRecords: [{ recordId: "123" , recordType: "user" }],
metadata: { table: "users" },
success: true ,
},
]);
Parameters:
Parameter Type Description actionsActionModel[]List of action records
Returns: SpanWrapper (for chaining)
setSuccess
Mark the span as successful.
Returns: SpanWrapper (for chaining)
setError
Mark the span as failed with an error message.
span . setError ( "Failed to connect to database" );
Parameters:
Parameter Type Description messagestringError message
Returns: SpanWrapper (for chaining)
end
End the span. Required in TypeScript - spans won’t be exported until end() is called.
Returns: void
Always call span.end() in TypeScript, preferably in a finally block to ensure spans are closed even when errors occur.
Types and Interfaces
SpanType
Enum for categorizing spans.
import { SpanType } from "netra-sdk" ;
SpanType . SPAN ; // General operations (default)
SpanType . GENERATION ; // LLM completions, image generation
SpanType . EMBEDDING ; // Vector embedding operations
SpanType . TOOL ; // Function calls, API requests
SpanType . AGENT ; // AI agent operations
UsageModel
Interface for tracking token usage and costs.
interface UsageModel {
model : string ;
costInUsd ?: number ;
usageType ?: string ;
unitsUsed ?: number ;
}
Example:
const usage : UsageModel = {
model: "gpt-4" ,
costInUsd: 0.0045 ,
usageType: "chat" ,
unitsUsed: 1 ,
};
ActionModel
Interface for tracking actions and tool calls.
interface ActionModel {
action : string ;
actionType : string ;
affectedRecords ?: Array <{
recordId : string ;
recordType : string ;
}>;
metadata ?: Record < string , string >;
success : boolean ;
}
Example:
const action : ActionModel = {
action: "API" ,
actionType: "CALL" ,
affectedRecords: [{ recordId: "order-123" , recordType: "order" }],
metadata: {
endpoint: "/api/orders" ,
method: "POST" ,
statusCode: "201" ,
},
success: true ,
};
Decorators
TypeScript decorators for easy function instrumentation.
TypeScript decorators require "experimentalDecorators": true in your tsconfig.json.
@agent
Mark a function or class as an AI agent.
import { agent } from "netra-sdk/decorators" ;
@ agent
async function researchAgent ( query : string ) {
return await performResearch ( query );
}
@ agent ({ name: "customer-support" })
async function supportAgent ( request : Request ) {
return await handleRequest ( request );
}
@task
Mark a function as a task or tool.
import { task } from "netra-sdk/decorators" ;
@ task
async function fetchData ( query : string ) {
return await database . query ( query );
}
@ task ({ name: "web-search" })
async function searchWeb ( query : string ) {
return await searchApi . search ( query );
}
@workflow
Mark a function as a workflow.
import { workflow } from "netra-sdk/decorators" ;
@ workflow
async function processOrder ( order : Order ) {
await validateOrder ( order );
await processPayment ( order );
await fulfillOrder ( order );
}
Instruments
Available instrumentations for auto-tracing.
import { NetraInstruments } from "netra-sdk" ;
// LLM Providers
NetraInstruments . OPENAI ;
NetraInstruments . GOOGLE_GENAI ;
NetraInstruments . MISTRAL ;
NetraInstruments . GROQ ;
NetraInstruments . VERTEX_AI ;
NetraInstruments . TOGETHER ;
// AI Frameworks
NetraInstruments . LANGCHAIN ;
NetraInstruments . LANGGRAPH ;
NetraInstruments . LLAMAINDEX ;
// Vector Databases
NetraInstruments . PINECONE ;
NetraInstruments . QDRANT ;
NetraInstruments . CHROMADB ;
// HTTP Clients
NetraInstruments . HTTP ;
NetraInstruments . HTTPS ;
NetraInstruments . FETCH ;
// Web Frameworks
NetraInstruments . EXPRESS ;
NetraInstruments . FASTIFY ;
NetraInstruments . NESTJS ;
// Databases
NetraInstruments . PRISMA ;
NetraInstruments . TYPEORM ;
NetraInstruments . MONGODB ;
NetraInstruments . POSTGRES ;
NetraInstruments . MYSQL ;
NetraInstruments . REDIS ;
// Message Queues
NetraInstruments . KAFKA ;
NetraInstruments . RABBITMQ ;
Complete Example
import { Netra , SpanType , NetraInstruments } from "netra-sdk" ;
import OpenAI from "openai" ;
// Initialize SDK (must await to ensure instrumentations are ready)
await Netra . init ({
appName: "my-ai-app" ,
headers: `x-api-key= ${ process . env . NETRA_API_KEY } ` ,
environment: "production" ,
instruments: new Set ([ NetraInstruments . OPENAI ]),
});
// Set context
Netra . setUserId ( "user-123" );
Netra . setSessionId ( "session-abc" );
// Create a traced operation
async function chatWithAI ( userMessage : string ) : Promise < string > {
const span = Netra . startSpan ( "chat-completion" , {}, undefined , SpanType . GENERATION );
span . setPrompt ( userMessage );
span . setModel ( "gpt-4" );
span . setLlmSystem ( "openai" );
try {
const client = new OpenAI ();
const response = await client . chat . completions . create ({
model: "gpt-4" ,
messages: [{ role: "user" , content: userMessage }],
});
// Calculate cost based on token usage
const promptCost = (( response . usage ?. prompt_tokens || 0 ) / 1000 ) * 0.03 ;
const completionCost = (( response . usage ?. completion_tokens || 0 ) / 1000 ) * 0.06 ;
const totalCost = promptCost + completionCost ;
span . setUsage ([
{
model: "gpt-4" ,
costInUsd: totalCost ,
usageType: "chat" ,
unitsUsed: 1 ,
},
]);
span . setSuccess ();
return response . choices [ 0 ]. message . content || "" ;
} catch ( error : any ) {
span . setError ( error . message );
throw error ;
} finally {
span . end ();
}
}
// Use the function
const result = await chatWithAI ( "What is the capital of France?" );
console . log ( result );
// Shutdown gracefully
await Netra . shutdown ();
Express.js Integration
Example of integrating Netra with Express.js:
import express from "express" ;
import { Netra , NetraInstruments } from "netra-sdk" ;
async function main () {
// Initialize before creating the app (must await)
await Netra . init ({
appName: "my-api" ,
headers: `x-api-key= ${ process . env . NETRA_API_KEY } ` ,
instruments: new Set ([ NetraInstruments . EXPRESS , NetraInstruments . OPENAI ]),
});
const app = express ();
// Middleware to set user context
app . use (( req , res , next ) => {
if ( req . headers [ "x-user-id" ]) {
Netra . setUserId ( req . headers [ "x-user-id" ] as string );
}
if ( req . headers [ "x-session-id" ]) {
Netra . setSessionId ( req . headers [ "x-session-id" ] as string );
}
next ();
});
app . post ( "/api/chat" , async ( req , res ) => {
const span = Netra . startSpan ( "handle-chat-request" );
try {
const { message } = req . body ;
span . setAttribute ( "input.length" , message . length );
const response = await processMessage ( message );
span . setSuccess ();
res . json ({ response });
} catch ( error : any ) {
span . setError ( error . message );
res . status ( 500 ). json ({ error: error . message });
} finally {
span . end ();
}
});
// Graceful shutdown
process . on ( "SIGTERM" , async () => {
await Netra . shutdown ();
process . exit ( 0 );
});
app . listen ( 3000 );
}
main ();
Key Differences from Python SDK
Feature Python TypeScript Initialization Netra.init() (sync)await Netra.init() (async, waits for instrumentations)Span lifecycle Context manager (with statement) Manual end() call required Naming convention snake_casecamelCaseInstruments enum InstrumentsNetraInstrumentsShutdown Netra.shutdown()await Netra.shutdown()Async Context managers work with sync/async Always use async/await
Next Steps