@lmnr-ai/lmnr 0.4.19 → 0.4.21
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/cli.js +1 -1
- package/dist/cli.js.map +1 -1
- package/dist/cli.mjs +1 -1
- package/dist/cli.mjs.map +1 -1
- package/dist/index.d.mts +26 -2
- package/dist/index.d.ts +26 -2
- package/dist/index.js +51 -14
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +49 -13
- package/dist/index.mjs.map +1 -1
- package/package.json +1 -1
- package/src/decorators.ts +62 -0
- package/src/index.ts +1 -1
- package/src/laminar.ts +19 -2
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/index.ts","../src/laminar.ts","../src/sdk/errors/index.ts","../src/sdk/tracing/index.ts","../src/sdk/tracing/tracing.ts","../src/sdk/tracing/attributes.ts","../src/sdk/configuration/index.ts","../src/sdk/tracing/decorators.ts","../src/utils.ts","../src/evaluations.ts","../src/datasets.ts","../src/decorators.ts"],"sourcesContent":["export {\n NodeInput,\n PipelineRunResponse,\n PipelineRunRequest,\n ChatMessage,\n Event,\n EvaluateEvent,\n} from './types';\n\nexport { Laminar } from './laminar';\nexport { evaluate, Datapoint, HumanEvaluator } from './evaluations';\nexport { EvaluationDataset as Dataset, LaminarDataset } from './datasets';\nexport { observe } from './decorators';\nexport { LaminarAttributes } from './sdk/tracing/attributes';\nexport { Span } from '@opentelemetry/api';\n","import {\n PipelineRunResponse,\n PipelineRunRequest,\n EvaluationDatapoint,\n CreateEvaluationResponse,\n GetDatapointsResponse\n} from './types';\nimport {\n Attributes,\n AttributeValue,\n Context,\n context as contextApi,\n isSpanContextValid,\n Span,\n TimeInput,\n trace,\n TraceFlags\n} from '@opentelemetry/api';\nimport { InitializeOptions, initialize as traceloopInitialize } from './sdk/node-server-sdk'\nimport { isStringUUID, otelSpanIdToUUID, otelTraceIdToUUID, uuidToOtelTraceId } from './utils';\nimport { OTLPTraceExporter } from '@opentelemetry/exporter-trace-otlp-grpc';\nimport { Metadata } from '@grpc/grpc-js';\nimport { ASSOCIATION_PROPERTIES_KEY, getSpanPath, getTracer, SPAN_PATH_KEY } from './sdk/tracing/tracing';\nimport { forceFlush } from './sdk/node-server-sdk';\nimport { SESSION_ID, USER_ID, LaminarAttributes, SPAN_OUTPUT, SPAN_TYPE, SPAN_INPUT, OVERRIDE_PARENT_SPAN } from './sdk/tracing/attributes';\nimport { RandomIdGenerator } from '@opentelemetry/sdk-trace-base';\n\n\ninterface LaminarInitializeProps {\n projectApiKey?: string;\n env?: Record<string, string>;\n baseUrl?: string;\n httpPort?: number;\n grpcPort?: number;\n instrumentModules?: InitializeOptions[\"instrumentModules\"];\n}\n\nexport class Laminar {\n private static baseHttpUrl: string;\n private static baseGrpcUrl: string;\n private static projectApiKey: string;\n private static env: Record<string, string> = {};\n private static isInitialized: boolean = false;\n\n /**\n * Initialize Laminar context across the application.\n * This method must be called before using any other Laminar methods or decorators.\n *\n * @param project_api_key - Laminar project api key. You can generate one by going\n * to the projects settings page on the Laminar dashboard.\n * If not specified, it will try to read from the LMNR_PROJECT_API_KEY environment variable.\n * @param env - Default environment passed to `run` requests, unless overriden at request\n * time. Usually, model provider keys are stored here.\n * @param baseUrl - Laminar API url. Do not include the port, use\n * `httpPort` and `grpcPort` instead.\n * If not specified, defaults to https://api.lmnr.ai.\n * @param httpPort - Laminar API http port.\n * If not specified, defaults to 443.\n * @param grpcPort - Laminar API grpc port.\n * If not specified, defaults to 8443.\n * @param instrumentModules - List of modules to instrument.\n * If not specified, all auto-instrumentable modules will be instrumented, which include\n * LLM calls (OpenAI, Anthropic, etc), Langchain, VectorDB calls (Pinecone, Qdrant, etc).\n * Pass an empty object {} to disable any kind of automatic instrumentation.\n * If you only want to auto-instrument specific modules, then pass them in the object.\n * \n * @example\n * import { Laminar as L } from '@lmnr-ai/lmnr';\n * import { OpenAI } from 'openai';\n * import * as ChainsModule from \"langchain/chains\";\n * \n * // Initialize Laminar while auto-instrumenting Langchain and OpenAI modules.\n * L.initialize({ projectApiKey: \"<LMNR_PROJECT_API_KEY>\", instrumentModules: {\n * langchain: {\n * chainsModule: ChainsModule\n * },\n * openAI: OpenAI\n * } });\n *\n * @throws {Error} - If project API key is not set\n */\n public static initialize({\n projectApiKey,\n env,\n baseUrl,\n httpPort,\n grpcPort,\n instrumentModules\n }: LaminarInitializeProps) {\n\n let key = projectApiKey ?? process.env.LMNR_PROJECT_API_KEY;\n if (key === undefined) {\n throw new Error(\n 'Please initialize the Laminar object with your project API key ' +\n 'or set the LMNR_PROJECT_API_KEY environment variable'\n );\n }\n this.projectApiKey = key;\n if (baseUrl?.match(/:\\d{1,5}$/g)) {\n throw new Error(\n 'Port should be passed separately in `httpPort` and `grpcPort`'\n );\n }\n\n this.baseHttpUrl = `${baseUrl ?? 'https://api.lmnr.ai'}:${httpPort ?? 443}`;\n this.baseGrpcUrl = `${baseUrl ?? 'https://api.lmnr.ai'}:${grpcPort ?? 8443}`;\n\n this.isInitialized = true;\n this.env = env ?? {};\n\n const metadata = new Metadata();\n metadata.set('authorization', `Bearer ${this.projectApiKey}`);\n const exporter = new OTLPTraceExporter({\n url: this.baseGrpcUrl,\n metadata,\n });\n\n traceloopInitialize({\n exporter,\n silenceInitializationMessage: true,\n instrumentModules,\n disableBatch: false,\n });\n }\n\n /**\n * Check if Laminar has been initialized. Utility to make sure other methods\n * are called after initialization.\n */\n public static initialized(): boolean {\n return this.isInitialized;\n }\n\n /**\n * Sets the environment that will be sent to Laminar requests.\n * \n * @param env - The environment variables to override. If not provided, the\n * current environment will not be modified.\n */\n public static setEnv(env?: Record<string, string>) {\n if (env) {\n this.env = env;\n }\n }\n\n /**\n * Sets the project API key for authentication with Laminar.\n *\n * @param projectApiKey - The API key to be set. If not provided, the existing\n * API key will not be modified.\n */\n public static setProjectApiKey(projectApiKey?: string) {\n if (projectApiKey) {\n this.projectApiKey = projectApiKey;\n }\n }\n\n /**\n * Runs the pipeline with the given inputs\n *\n * @param pipeline - The name of the Laminar pipeline. Pipeline must have a target version.\n * @param inputs - The inputs for the pipeline. Map from an input node name to input data.\n * @param env - The environment variables for the pipeline execution.\n * Typically used for model provider keys.\n * @param metadata - Additional metadata for the pipeline run.\n * @param currentSpanId - The ID of the current span.\n * @param currentTraceId - The ID of the current trace.\n * @returns A promise that resolves to the response of the pipeline run.\n * @throws An error if the Laminar object is not initialized with a project API\n * key or if the request fails.\n */\n public static async run({\n pipeline,\n inputs,\n env,\n metadata = {},\n currentSpanId,\n currentTraceId,\n }: PipelineRunRequest): Promise<PipelineRunResponse> {\n const currentSpan = trace.getActiveSpan();\n let parentSpanId: string | undefined;\n let traceId: string | undefined;\n if (currentSpan !== undefined && isSpanContextValid(currentSpan.spanContext())) {\n parentSpanId = currentSpanId ?? otelSpanIdToUUID(currentSpan.spanContext().spanId);\n traceId = currentTraceId ?? otelTraceIdToUUID(currentSpan.spanContext().traceId);\n } else {\n parentSpanId = currentSpanId;\n traceId = currentTraceId;\n }\n if (this.projectApiKey === undefined) {\n throw new Error(\n 'Please initialize the Laminar object with your project API key ' +\n 'or set the LMNR_PROJECT_API_KEY environment variable'\n );\n }\n const envirionment = env === undefined ? this.env : env;\n\n const response = await fetch(`${this.baseHttpUrl}/v1/pipeline/run`, {\n method: 'POST',\n headers: this.getHeaders(),\n body: JSON.stringify({\n inputs,\n pipeline,\n env: envirionment,\n metadata,\n parentSpanId,\n traceId,\n })\n });\n\n if (!response.ok) {\n throw new Error(`Failed to run pipeline ${pipeline}. Response: ${response.statusText}`);\n }\n try {\n return await response.json() as PipelineRunResponse;\n } catch (error) {\n throw new Error(`Failed to parse response from pipeline ${pipeline}. Error: ${error}`);\n }\n }\n\n /**\n * Associates an event with the current span. If event with such name never\n * existed, Laminar will create a new event and infer its type from the value.\n * If the event already exists, Laminar will append the value to the event\n * if and only if the value is of a matching type. Otherwise, the event won't\n * be recorded. Supported types are string, number, and boolean. If the value\n * is `null`, event is considered a boolean tag with the value of `true`.\n *\n * @param name - The name of the event.\n * @param value - The value of the event. Must be a primitive type. If not\n * specified, boolean true is assumed in the backend.\n * @param timestamp - The timestamp of the event. If not specified, relies on\n * the underlying OpenTelemetry implementation.\n * If specified as an integer, it must be epoch nanoseconds.\n */\n public static event(\n name: string,\n value?: AttributeValue,\n timestamp?: TimeInput,\n ) {\n const currentSpan = trace.getActiveSpan();\n if (currentSpan === undefined || !isSpanContextValid(currentSpan.spanContext())) {\n console.warn(\"Laminar().event()\\` called outside of span context.\" +\n ` Event '${name}' will not be recorded in the trace.` +\n \" Make sure to annotate the function with a decorator\"\n );\n return;\n }\n\n const event: Attributes = {\n \"lmnr.event.type\": \"default\",\n }\n if (value !== undefined) {\n event[\"lmnr.event.value\"] = value;\n }\n\n currentSpan.addEvent(name, event, timestamp);\n }\n\n /**\n * Sets the session information for the current span and returns the\n * context to use for the following spans.\n * \n * @param sessionId - The session ID to associate with the context.\n * @param userId - The user ID to associate with the context.\n * @returns The updated context with the association properties.\n * \n * @example\n * import { context as contextApi } from '@opentelemetry/api';\n * import { Laminar } from '@lmnr-ai/laminar';\n * const context = Laminar.contextWithSession({ sessionId: \"1234\", userId: \"5678\" });\n * contextApi.with(context, () => {\n * // Your code here\n * });\n */\n public static contextWithSession({\n sessionId,\n userId\n }: { sessionId?: string, userId?: string }): Context {\n const currentSpan = trace.getActiveSpan();\n if (currentSpan !== undefined && isSpanContextValid(currentSpan.spanContext())) {\n if (sessionId) {\n currentSpan.setAttribute(SESSION_ID, sessionId);\n }\n if (userId) {\n currentSpan.setAttribute(USER_ID, userId);\n }\n }\n let associationProperties = {};\n if (sessionId) {\n associationProperties = { ...associationProperties, \"session_id\": sessionId };\n }\n if (userId) {\n associationProperties = { ...associationProperties, \"user_id\": userId };\n }\n\n let entityContext = contextApi.active();\n const currentAssociationProperties = entityContext.getValue(ASSOCIATION_PROPERTIES_KEY);\n if (associationProperties) {\n entityContext = entityContext.setValue(\n ASSOCIATION_PROPERTIES_KEY,\n { ...(currentAssociationProperties ?? {}), ...associationProperties },\n );\n }\n\n return entityContext;\n }\n\n /**\n * Set attributes for the current span. Useful for manual\n * instrumentation.\n * @param attributes - The attributes to set for the current span.\n * \n * @example\n * import { Laminar as L, observe } from '@lmnr-ai/laminar';\n * await observe({ name: 'mySpanName', spanType: 'LLM' }, async (msg: string) => {\n * const response = await myCustomCallToOpenAI(msg);\n * L.setSpanAttributes({\n * [LaminarAttributes.PROVIDER]: 'openai',\n * [LaminarAttributes.REQUEST_MODEL]: \"requested_model\",\n * [LaminarAttributes.RESPONSE_MODEL]: response.model,\n * [LaminarAttributes.INPUT_TOKEN_COUNT]: response.usage.prompt_tokens,\n * [LaminarAttributes.OUTPUT_TOKEN_COUNT]: response.usage.completion_tokens,\n * })\n * }, userMessage);\n */\n public static setSpanAttributes(\n attributes: Record<typeof LaminarAttributes[keyof typeof LaminarAttributes], AttributeValue>\n ) {\n const currentSpan = trace.getActiveSpan();\n if (currentSpan !== undefined && isSpanContextValid(currentSpan.spanContext())) {\n for (const [key, value] of Object.entries(attributes)) {\n currentSpan.setAttribute(key, value);\n }\n }\n }\n\n /**\n * Set the output of the current span. Useful for manual instrumentation.\n * @param output - Output of the span. Will be sent as an attribute, so must be serializable to JSON.\n */\n public static setSpanOutput(output: any) {\n if (output == null) {\n return;\n }\n const currentSpan = trace.getActiveSpan();\n if (currentSpan !== undefined && isSpanContextValid(currentSpan.spanContext())) {\n currentSpan.setAttribute(SPAN_OUTPUT, JSON.stringify(output));\n }\n }\n\n /**\n * Start a new span, but don't set it as active. Useful for\n * manual instrumentation. If span type is 'LLM', you should report usage\n * manually. See {@link setSpanAttributes} for more information.\n * \n * @param name - name of the span\n * @param input - input to the span. Will be sent as an attribute, so must\n * be JSON serializable\n * @param span_type - type of the span. Defaults to 'DEFAULT'\n * @param context - raw OpenTelemetry context to bind the span to.\n * @param traceId - [EXPERIMENTAL] override the trace id for the span. If not\n * provided, uses the current trace id.\n * @returns The started span.\n * \n * @example\n * import { Laminar, observe } from '@lmnr-ai/lmnr';\n * const foo = async (span: Span) => {\n * await Laminar.withSpan(span, async () => {\n * await observe({ name: 'foo' }, async () => {\n * // Your code here\n * })\n * })\n * };\n * const bar = async (span: Span) => {\n * await Laminar.withSpan(span, async () => {\n * await openai_client.chat.completions.create();\n * })\n * };\n * \n * const parentSpan = Laminar.startSpan({name: \"outer\"});\n * foo(parentSpan);\n * await bar(parentSpan);\n * // IMPORTANT: Don't forget to end the span!\n * parentSpan.end();\n * \n * // Results in:\n * // | outer\n * // | | foo\n * // | | | ...\n * // | | bar\n * // | | | openai.chat\n */\n public static startSpan({\n name,\n input,\n spanType,\n context,\n traceId,\n }: {\n name: string,\n input?: any,\n spanType?: 'LLM' | 'DEFAULT',\n context?: Context,\n traceId?: string,\n }): Span {\n let entityContext = context ?? contextApi.active();\n const currentSpanPath = getSpanPath(entityContext);\n const spanPath = currentSpanPath ? `${currentSpanPath}.${name}` : name;\n entityContext = entityContext.setValue(SPAN_PATH_KEY, spanPath);\n if (traceId) {\n if (isStringUUID(traceId)) {\n const spanContext = {\n traceId: uuidToOtelTraceId(traceId),\n spanId: new RandomIdGenerator().generateSpanId(),\n traceFlags: TraceFlags.SAMPLED,\n isRemote: false,\n };\n entityContext = trace.setSpanContext(entityContext, spanContext);\n } else {\n console.warn(`Invalid trace ID ${traceId}. Expected a UUID.`);\n }\n }\n const attributes = {\n [SPAN_TYPE]: spanType ?? 'DEFAULT',\n [SPAN_PATH_KEY]: spanPath,\n }\n const span = getTracer().startSpan(name, { attributes }, entityContext);\n if (traceId) {\n span.setAttribute(OVERRIDE_PARENT_SPAN, true);\n }\n if (input) {\n span.setAttribute(SPAN_INPUT, JSON.stringify(input));\n }\n return span;\n }\n\n /**\n * A utility wrapper around OpenTelemetry's `context.with()`. Useful for \n * passing spans around in manual instrumentation:\n * \n * @param span - Parent span to bind the execution to.\n * @param fn - Function to execute within the span context.\n * @param endOnExit - Whether to end the span after the function has\n * executed. Defaults to `false`. If `false`, you MUST manually call\n * `span.end()` at the end of the execution, so that spans are not lost.\n * @returns The result of the function execution.\n * \n * See {@link startSpan} docs for a usage example\n */\n public static withSpan<T>(span: Span, fn: () => T, endOnExit?: boolean): T {\n return contextApi.with(trace.setSpan(contextApi.active(), span), () => {\n try{\n const result = fn();\n return result;\n }\n finally {\n if (endOnExit !== undefined && endOnExit) {\n span.end();\n }\n }\n });\n }\n\n public static async shutdown() {\n await forceFlush();\n }\n\n public static async createEvaluation<D, T, O>({\n groupId,\n name,\n data\n }: {\n groupId?: string,\n name?: string,\n data: EvaluationDatapoint<D, T, O>[]\n }): Promise<CreateEvaluationResponse> {\n let body = '';\n try {\n body = JSON.stringify({\n groupId: groupId ?? null,\n name: name ?? null,\n points: data,\n });\n } catch (error) {\n throw new Error(`Failed to serialize evaluation data for ${name}. Error: ${error}`);\n }\n const response = await fetch(`${this.baseHttpUrl}/v1/evaluations`, {\n method: 'POST',\n headers: this.getHeaders(),\n body,\n });\n\n if (!response.ok) {\n throw new Error(`Failed to create evaluation ${name}. Response: ${response.statusText}`);\n }\n\n return await response.json() as CreateEvaluationResponse;\n }\n\n public static async getDatapoints<D, T>({\n datasetName,\n offset,\n limit,\n }: {\n datasetName: string,\n offset: number,\n limit: number,\n }): Promise<GetDatapointsResponse<D, T>> {\n const params = new URLSearchParams({\n name: datasetName,\n offset: offset.toString(),\n limit: limit.toString()\n });\n const response = await fetch(`${this.baseHttpUrl}/v1/datasets/datapoints?${params.toString()}`, {\n method: 'GET',\n headers: this.getHeaders(),\n });\n\n if (!response.ok) {\n throw new Error(`Failed to get datapoints for dataset ${datasetName}. Response: ${response.statusText}`);\n }\n\n return await response.json() as GetDatapointsResponse<D, T>;\n }\n\n private static getHeaders() {\n return {\n \"Content-Type\": \"application/json\",\n \"Authorization\": `Bearer ${this.projectApiKey}`,\n };\n };\n}\n","/**\n * The severity of an error.\n */\nexport const SEVERITY = {\n Warning: \"Warning\",\n Error: \"Error\",\n Critical: \"Critical\",\n} as const;\n\nexport type Severity = (typeof SEVERITY)[keyof typeof SEVERITY];\n\n/**\n * Base class for all Traceloop errors.\n */\nexport class TraceloopError extends Error {\n /**\n * The severity of the error.\n */\n severity: Severity;\n /**\n * The underlying cause of the error.\n */\n underlyingCause?: Error;\n\n constructor(message: string, severity: Severity = SEVERITY.Error) {\n super(message);\n this.severity = severity;\n }\n}\n\nexport class NotInitializedError extends TraceloopError {\n constructor() {\n super(\n `The Traceloop SDK must be initialized by calling the \"initialize\" function prior to use.`,\n SEVERITY.Critical,\n );\n }\n}\n\nexport class InitializationError extends TraceloopError {\n constructor(message?: string, cause?: Error) {\n super(message ?? \"Failed to initialize Traceloop SDK\", SEVERITY.Critical);\n this.underlyingCause = cause;\n }\n}\n\nexport class ArgumentNotProvidedError extends TraceloopError {\n constructor(argumentName: string) {\n super(`The \"${argumentName}\" argument is required and must be a string.`);\n }\n}\n\nexport class PromptNotFoundError extends TraceloopError {\n constructor(key: string) {\n super(`The prompt \"${key}\" was not found in the registry.`);\n }\n}\n","/* eslint-disable @typescript-eslint/no-var-requires */\nimport { baggageUtils } from \"@opentelemetry/core\";\nimport { Span, context, diag } from \"@opentelemetry/api\";\nimport { OTLPTraceExporter } from \"@opentelemetry/exporter-trace-otlp-proto\";\nimport { Instrumentation } from \"@opentelemetry/instrumentation\";\nimport { InitializeOptions } from \"../interfaces\";\nimport {\n ASSOCIATION_PROPERTIES_KEY,\n SPAN_PATH_KEY,\n} from \"./tracing\";\nimport { _configuration } from \"../configuration\";\nimport { NodeTracerProvider, SimpleSpanProcessor, BatchSpanProcessor } from \"@opentelemetry/sdk-trace-node\";\nimport { registerInstrumentations } from \"@opentelemetry/instrumentation\";\nimport { AnthropicInstrumentation } from \"@traceloop/instrumentation-anthropic\";\nimport { OpenAIInstrumentation } from \"@traceloop/instrumentation-openai\";\nimport { AzureOpenAIInstrumentation } from \"@traceloop/instrumentation-azure\";\nimport { LlamaIndexInstrumentation } from \"@traceloop/instrumentation-llamaindex\";\nimport {\n AIPlatformInstrumentation,\n VertexAIInstrumentation,\n} from \"@traceloop/instrumentation-vertexai\";\nimport { BedrockInstrumentation } from \"@traceloop/instrumentation-bedrock\";\nimport { CohereInstrumentation } from \"@traceloop/instrumentation-cohere\";\nimport { PineconeInstrumentation } from \"@traceloop/instrumentation-pinecone\";\nimport { LangChainInstrumentation } from \"@traceloop/instrumentation-langchain\";\nimport { ChromaDBInstrumentation } from \"@traceloop/instrumentation-chromadb\";\nimport { QdrantInstrumentation } from \"@traceloop/instrumentation-qdrant\";\nimport { ASSOCIATION_PROPERTIES, ASSOCIATION_PROPERTIES_OVERRIDES, SPAN_INSTRUMENTATION_SOURCE, SPAN_PATH } from \"./attributes\";\n\nlet _spanProcessor: SimpleSpanProcessor | BatchSpanProcessor;\nlet openAIInstrumentation: OpenAIInstrumentation | undefined;\nlet anthropicInstrumentation: AnthropicInstrumentation | undefined;\nlet azureOpenAIInstrumentation: AzureOpenAIInstrumentation | undefined;\nlet cohereInstrumentation: CohereInstrumentation | undefined;\nlet vertexaiInstrumentation: VertexAIInstrumentation | undefined;\nlet aiplatformInstrumentation: AIPlatformInstrumentation | undefined;\nlet bedrockInstrumentation: BedrockInstrumentation | undefined;\nlet langchainInstrumentation: LangChainInstrumentation | undefined;\nlet llamaIndexInstrumentation: LlamaIndexInstrumentation | undefined;\nlet pineconeInstrumentation: PineconeInstrumentation | undefined;\nlet chromadbInstrumentation: ChromaDBInstrumentation | undefined;\nlet qdrantInstrumentation: QdrantInstrumentation | undefined;\n\n\nconst instrumentations: Instrumentation[] = [];\n\nconst initInstrumentations = () => {\n const enrichTokens = false;\n\n openAIInstrumentation = new OpenAIInstrumentation({\n enrichTokens,\n });\n instrumentations.push(openAIInstrumentation);\n\n anthropicInstrumentation = new AnthropicInstrumentation();\n instrumentations.push(anthropicInstrumentation);\n\n azureOpenAIInstrumentation = new AzureOpenAIInstrumentation();\n instrumentations.push(azureOpenAIInstrumentation);\n\n cohereInstrumentation = new CohereInstrumentation();\n instrumentations.push(cohereInstrumentation);\n\n vertexaiInstrumentation = new VertexAIInstrumentation();\n instrumentations.push(vertexaiInstrumentation);\n\n aiplatformInstrumentation = new AIPlatformInstrumentation();\n instrumentations.push(aiplatformInstrumentation);\n\n bedrockInstrumentation = new BedrockInstrumentation();\n instrumentations.push(bedrockInstrumentation);\n\n pineconeInstrumentation = new PineconeInstrumentation();\n instrumentations.push(pineconeInstrumentation);\n\n langchainInstrumentation = new LangChainInstrumentation();\n instrumentations.push(langchainInstrumentation);\n\n llamaIndexInstrumentation = new LlamaIndexInstrumentation();\n instrumentations.push(llamaIndexInstrumentation);\n\n chromadbInstrumentation = new ChromaDBInstrumentation();\n instrumentations.push(chromadbInstrumentation);\n\n qdrantInstrumentation = new QdrantInstrumentation();\n instrumentations.push(qdrantInstrumentation);\n};\n\nconst manuallyInitInstrumentations = (\n instrumentModules: InitializeOptions[\"instrumentModules\"],\n) => {\n const enrichTokens = false;\n\n instrumentations.length = 0;\n\n if (instrumentModules?.openAI) {\n openAIInstrumentation = new OpenAIInstrumentation({\n enrichTokens,\n });\n instrumentations.push(openAIInstrumentation);\n openAIInstrumentation.manuallyInstrument(instrumentModules.openAI);\n }\n\n if (instrumentModules?.anthropic) {\n anthropicInstrumentation = new AnthropicInstrumentation();\n instrumentations.push(anthropicInstrumentation);\n anthropicInstrumentation.manuallyInstrument(instrumentModules.anthropic);\n }\n\n if (instrumentModules?.azureOpenAI) {\n const instrumentation = new AzureOpenAIInstrumentation();\n instrumentations.push(instrumentation as Instrumentation);\n azureOpenAIInstrumentation = instrumentation;\n instrumentation.manuallyInstrument(instrumentModules.azureOpenAI);\n }\n\n if (instrumentModules?.cohere) {\n cohereInstrumentation = new CohereInstrumentation();\n instrumentations.push(cohereInstrumentation);\n cohereInstrumentation.manuallyInstrument(instrumentModules.cohere);\n }\n\n if (instrumentModules?.google_vertexai) {\n vertexaiInstrumentation = new VertexAIInstrumentation();\n instrumentations.push(vertexaiInstrumentation);\n vertexaiInstrumentation.manuallyInstrument(\n instrumentModules.google_vertexai,\n );\n }\n\n if (instrumentModules?.google_aiplatform) {\n aiplatformInstrumentation = new AIPlatformInstrumentation();\n instrumentations.push(aiplatformInstrumentation);\n aiplatformInstrumentation.manuallyInstrument(\n instrumentModules.google_aiplatform,\n );\n }\n\n if (instrumentModules?.bedrock) {\n bedrockInstrumentation = new BedrockInstrumentation();\n instrumentations.push(bedrockInstrumentation);\n bedrockInstrumentation.manuallyInstrument(instrumentModules.bedrock);\n }\n\n if (instrumentModules?.pinecone) {\n const instrumentation = new PineconeInstrumentation();\n instrumentations.push(instrumentation as Instrumentation);\n instrumentation.manuallyInstrument(instrumentModules.pinecone);\n }\n\n if (instrumentModules?.langchain) {\n langchainInstrumentation = new LangChainInstrumentation();\n instrumentations.push(langchainInstrumentation);\n langchainInstrumentation.manuallyInstrument(instrumentModules.langchain);\n }\n\n if (instrumentModules?.llamaIndex) {\n llamaIndexInstrumentation = new LlamaIndexInstrumentation();\n instrumentations.push(llamaIndexInstrumentation);\n llamaIndexInstrumentation.manuallyInstrument(instrumentModules.llamaIndex);\n }\n\n if (instrumentModules?.chromadb) {\n chromadbInstrumentation = new ChromaDBInstrumentation();\n instrumentations.push(chromadbInstrumentation);\n chromadbInstrumentation.manuallyInstrument(instrumentModules.chromadb);\n }\n\n if (instrumentModules?.qdrant) {\n qdrantInstrumentation = new QdrantInstrumentation();\n instrumentations.push(qdrantInstrumentation);\n qdrantInstrumentation.manuallyInstrument(instrumentModules.qdrant);\n }\n};\n\n/**\n * Initializes the Traceloop SDK.\n * Must be called once before any other SDK methods.\n *\n * @param options - The options to initialize the SDK. See the {@link InitializeOptions} for details.\n */\nexport const startTracing = (options: InitializeOptions) => {\n if (options.instrumentModules !== undefined) {\n // If options.instrumentModules is empty, it will not initialize anything,\n // so empty dict can essentially be passed to disable any kind of automatic instrumentation.\n manuallyInitInstrumentations(options.instrumentModules);\n } else {\n initInstrumentations();\n }\n\n if (!shouldSendTraces()) {\n openAIInstrumentation?.setConfig({\n traceContent: false,\n });\n azureOpenAIInstrumentation?.setConfig({\n traceContent: false,\n });\n llamaIndexInstrumentation?.setConfig({\n traceContent: false,\n });\n vertexaiInstrumentation?.setConfig({\n traceContent: false,\n });\n aiplatformInstrumentation?.setConfig({\n traceContent: false,\n });\n bedrockInstrumentation?.setConfig({\n traceContent: false,\n });\n cohereInstrumentation?.setConfig({\n traceContent: false,\n });\n chromadbInstrumentation?.setConfig({\n traceContent: false,\n });\n }\n\n const headers = process.env.TRACELOOP_HEADERS\n ? baggageUtils.parseKeyPairsIntoRecord(process.env.TRACELOOP_HEADERS)\n : { Authorization: `Bearer ${options.apiKey}` };\n\n const traceExporter =\n options.exporter ??\n new OTLPTraceExporter({\n url: `${options.baseUrl}/v1/traces`,\n headers,\n });\n _spanProcessor = options.disableBatch\n ? new SimpleSpanProcessor(traceExporter)\n : new BatchSpanProcessor(traceExporter);\n\n _spanProcessor.onStart = (span: Span) => {\n const spanPath = context.active().getValue(SPAN_PATH_KEY);\n if (spanPath) {\n span.setAttribute(SPAN_PATH, spanPath as string);\n }\n\n span.setAttribute(SPAN_INSTRUMENTATION_SOURCE, \"javascript\");\n\n // This sets the properties only if the context has them\n const associationProperties = context\n .active()\n .getValue(ASSOCIATION_PROPERTIES_KEY);\n if (associationProperties) {\n for (const [key, value] of Object.entries(associationProperties)) {\n if (Object.keys(ASSOCIATION_PROPERTIES_OVERRIDES).includes(key)) {\n span.setAttribute(ASSOCIATION_PROPERTIES_OVERRIDES[key], value);\n } else {\n span.setAttribute(`${ASSOCIATION_PROPERTIES}.${key}`, value);\n }\n }\n }\n };\n\n const provider = new NodeTracerProvider();\n provider.addSpanProcessor(_spanProcessor);\n provider.register();\n registerInstrumentations({\n instrumentations,\n tracerProvider: provider,\n });\n};\n\nexport const shouldSendTraces = () => {\n if (!_configuration) {\n return false;\n }\n\n if (\n _configuration.traceContent === false ||\n (process.env.TRACELOOP_TRACE_CONTENT || \"true\").toLowerCase() === \"false\"\n ) {\n return false;\n }\n\n return true;\n};\n\nexport const forceFlush = async () => {\n await _spanProcessor?.forceFlush();\n};\n","import { trace, createContextKey } from \"@opentelemetry/api\";\nimport { Context } from \"@opentelemetry/api/build/src/context/types\";\n\nconst TRACER_NAME = \"lmnr.tracer\";\nexport const SPAN_PATH_KEY = createContextKey(\"span_path\");\nexport const ASSOCIATION_PROPERTIES_KEY = createContextKey(\n \"association_properties\",\n);\n\nexport const getTracer = () => {\n return trace.getTracer(TRACER_NAME);\n};\n\nexport const getSpanPath = (entityContext: Context): string | undefined => {\n const path = entityContext.getValue(SPAN_PATH_KEY);\n\n return path ? `${path}` : undefined;\n};\n","import { SpanAttributes } from '@traceloop/ai-semantic-conventions';\n\nexport const SPAN_INPUT = \"lmnr.span.input\";\nexport const SPAN_OUTPUT = \"lmnr.span.output\";\nexport const SPAN_TYPE = \"lmnr.span.type\";\nexport const SPAN_PATH = \"lmnr.span.path\";\nexport const SPAN_INSTRUMENTATION_SOURCE = \"lmnr.span.instrumentation_source\";\nexport const OVERRIDE_PARENT_SPAN = \"lmnr.internal.override_parent_span\";\n\nexport const ASSOCIATION_PROPERTIES = \"lmnr.association.properties\";\nexport const SESSION_ID = \"lmnr.association.properties.session_id\";\nexport const USER_ID = \"lmnr.association.properties.user_id\";\nexport const TRACE_TYPE = \"lmnr.association.properties.trace_type\";\n\nexport const ASSOCIATION_PROPERTIES_OVERRIDES: Record<string, string> = {\n \"span_type\": SPAN_TYPE,\n};\n\nexport const LaminarAttributes = {\n // == This is the minimum set of attributes for a proper LLM span ==\n //\n // not SpanAttributes.LLM_USAGE_PROMPT_TOKENS\n INPUT_TOKEN_COUNT: \"gen_ai.usage.input_tokens\",\n // not SpanAttributes.LLM_USAGE_COMPLETION_TOKENS\n OUTPUT_TOKEN_COUNT: \"gen_ai.usage.output_tokens\",\n TOTAL_TOKEN_COUNT: SpanAttributes.LLM_USAGE_TOTAL_TOKENS,\n PROVIDER: SpanAttributes.LLM_SYSTEM,\n REQUEST_MODEL: SpanAttributes.LLM_REQUEST_MODEL,\n RESPONSE_MODEL: SpanAttributes.LLM_RESPONSE_MODEL,\n //\n // == End of minimum set ==\n // == Additional attributes ==\n //\n INPUT_COST: \"gen_ai.usage.input_cost\",\n OUTPUT_COST: \"gen_ai.usage.output_cost\",\n TOTAL_COST: \"gen_ai.usage.cost\",\n //\n // == End of additional attributes ==\n};\n","import { InitializeOptions } from \"../interfaces\";\nimport { startTracing } from \"../tracing\";\nimport { diag, DiagConsoleLogger, DiagLogLevel } from \"@opentelemetry/api\";\nimport { InitializationError } from \"../errors\";\n\nexport let _configuration: InitializeOptions | undefined;\n\n/**\n * Initializes the SDK.\n * Must be called once before any other SDK methods.\n *\n * @param options - The options to initialize the SDK. See the {@link InitializeOptions} for details.\n * @throws {InitializationError} if the configuration is invalid or if failed to fetch feature data.\n */\nexport const initialize = (options: InitializeOptions) => {\n if (_configuration) {\n return;\n }\n\n if (!options.baseUrl) {\n options.baseUrl =\n process.env.LMNR_BASE_URL || \"https://api.lmnr.ai:8443\";\n }\n if (!options.apiKey) {\n options.apiKey = process.env.LMNR_PROJECT_API_KEY;\n }\n if (options.apiKey && typeof options.apiKey !== \"string\") {\n throw new InitializationError('\"apiKey\" must be a string');\n }\n\n if (!options.appName) {\n options.appName = process.env.npm_package_name;\n }\n\n _configuration = Object.freeze(options);\n\n if (options.logLevel) {\n diag.setLogger(\n new DiagConsoleLogger(),\n logLevelToOtelLogLevel(options.logLevel),\n );\n }\n\n if (!options.silenceInitializationMessage) {\n console.log(\n `Laminar exporting traces to ${\n _configuration.exporter ? \"a custom exporter\" : _configuration.baseUrl\n }`,\n );\n }\n\n startTracing(_configuration);\n};\n\nconst logLevelToOtelLogLevel = (\n logLevel: \"debug\" | \"info\" | \"warn\" | \"error\",\n) => {\n switch (logLevel) {\n case \"debug\":\n return DiagLogLevel.DEBUG;\n case \"info\":\n return DiagLogLevel.INFO;\n case \"warn\":\n return DiagLogLevel.WARN;\n case \"error\":\n return DiagLogLevel.ERROR;\n }\n};\n","import { Span, TraceFlags, context, trace } from \"@opentelemetry/api\";\nimport { suppressTracing } from \"@opentelemetry/core\";\nimport {\n ASSOCIATION_PROPERTIES_KEY,\n getSpanPath,\n getTracer,\n SPAN_PATH_KEY,\n} from \"./tracing\";\nimport { shouldSendTraces } from \".\";\nimport { OVERRIDE_PARENT_SPAN, SPAN_INPUT, SPAN_OUTPUT } from \"./attributes\";\nimport { isStringUUID, uuidToOtelTraceId } from \"../../utils\";\nimport { RandomIdGenerator } from \"@opentelemetry/sdk-trace-base\";\n\nexport type DecoratorConfig = {\n name: string;\n associationProperties?: { [name: string]: string };\n inputParameters?: unknown[];\n suppressTracing?: boolean;\n traceId?: string;\n};\n\nexport function withEntity<\n A extends unknown[],\n F extends (...args: A) => ReturnType<F>,\n>(\n {\n name,\n associationProperties,\n inputParameters,\n suppressTracing: shouldSuppressTracing,\n traceId,\n }: DecoratorConfig,\n fn: F,\n thisArg?: ThisParameterType<F>,\n ...args: A\n) {\n let entityContext = context.active();\n\n const currentAssociationProperties = entityContext.getValue(ASSOCIATION_PROPERTIES_KEY);\n\n if (associationProperties) {\n entityContext = entityContext.setValue(\n ASSOCIATION_PROPERTIES_KEY,\n { ...(currentAssociationProperties ?? {}), ...associationProperties },\n );\n }\n\n const currentSpanPath = getSpanPath(entityContext);\n const spanPath = currentSpanPath ? `${currentSpanPath}.${name}` : name;\n entityContext = entityContext.setValue(SPAN_PATH_KEY, spanPath);\n if (traceId) {\n if (isStringUUID(traceId)) {\n const spanContext = {\n traceId: uuidToOtelTraceId(traceId),\n spanId: new RandomIdGenerator().generateSpanId(),\n traceFlags: TraceFlags.SAMPLED,\n isRemote: false,\n };\n entityContext = trace.setSpanContext(entityContext, spanContext);\n } else {\n console.warn(`Invalid trace ID ${traceId}. Expected a UUID.`);\n }\n }\n\n if (shouldSuppressTracing) {\n entityContext = suppressTracing(entityContext);\n }\n\n return context.with(entityContext, () =>\n getTracer().startActiveSpan(\n name,\n {},\n entityContext,\n async (span: Span) => {\n if (traceId && isStringUUID(traceId)) {\n span.setAttribute(OVERRIDE_PARENT_SPAN, true);\n }\n\n if (shouldSendTraces()) {\n try {\n const input = inputParameters ?? args;\n if (\n input.length === 1 &&\n typeof input[0] === \"object\" &&\n !(input[0] instanceof Map)\n ) {\n span.setAttribute(\n SPAN_INPUT,\n serialize(input[0]),\n );\n } else {\n // pass an array of the arguments without names\n // Need to convert it to hashmap from argument name to value, if we figure out how to do it elegantly\n span.setAttribute(\n SPAN_INPUT,\n serialize(input.length > 0 ? input : {}),\n );\n }\n } catch (error) {\n console.warn(\"Failed to serialize input\", error);\n }\n }\n\n // Remove span type from association properties after the span is created\n const { \"span_type\": spanType, ...rest } = associationProperties ?? {};\n entityContext = entityContext.setValue(\n ASSOCIATION_PROPERTIES_KEY,\n { ...(currentAssociationProperties ?? {}), ...rest },\n );\n\n const res = fn.apply(thisArg, args);\n\n if (res instanceof Promise) {\n return res.then((resolvedRes) => {\n try {\n if (shouldSendTraces()) {\n span.setAttribute(\n SPAN_OUTPUT,\n serialize(resolvedRes),\n );\n }\n } catch (error) {\n console.warn(\"Failed to serialize async output\", error);\n } finally {\n span.end();\n }\n\n return resolvedRes;\n });\n }\n try {\n if (shouldSendTraces()) {\n span.setAttribute(\n SPAN_OUTPUT,\n serialize(res),\n );\n }\n } catch (error) {\n console.warn(\"Failed to serialize output\", error);\n } finally {\n span.end();\n }\n\n return res;\n },\n ),\n );\n}\n\nfunction cleanInput(input: unknown): unknown {\n if (input instanceof Map) {\n return Array.from(input.entries());\n } else if (Array.isArray(input)) {\n return input.map((value) => cleanInput(value));\n } else if (!input) {\n return input;\n } else if (typeof input === \"object\") {\n // serialize object one by one\n const output: any = {};\n Object.entries(input as any).forEach(([key, value]) => {\n output[key] = cleanInput(value);\n });\n return output;\n }\n\n return input;\n}\n\nfunction serialize(input: unknown): string {\n return JSON.stringify(cleanInput(input));\n}\n","import { v4 as uuidv4 } from 'uuid';\n\nexport type StringUUID = `${string}-${string}-${string}-${string}-${string}`;\n\nexport const isStringUUID = (id: string): id is StringUUID => {\n return /^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/.test(id);\n}\n\nexport const newUUID = (): StringUUID => {\n // crypto.randomUUID is available in most of the modern browsers and node,\n // but is not available in \"insecure\" contexts, e.g. not https, not localhost\n // so we fallback to uuidv4 in those cases, which is less secure, but works\n // just fine.\n if (typeof crypto !== 'undefined' && typeof crypto.randomUUID === 'function') {\n return crypto.randomUUID();\n } else {\n return uuidv4() as `${string}-${string}-${string}-${string}-${string}`;\n }\n}\n\nexport const otelSpanIdToUUID = (spanId: string): string => {\n let id = spanId.toLowerCase();\n if (id.startsWith('0x')) {\n id = id.slice(2);\n }\n if (id.length !== 16) {\n console.warn(`Span ID ${spanId} is not 16 hex chars long. This is not a valid OpenTelemetry span ID.`);\n }\n\n if (!/^[0-9a-f]+$/.test(id)) {\n console.error(`Span ID ${spanId} is not a valid hex string. Generating a random UUID instead.`);\n return newUUID();\n }\n\n return id.padStart(32, '0').replace(/^(.{8})(.{4})(.{4})(.{4})(.{12})$/, '$1-$2-$3-$4-$5');\n}\n\nexport const otelTraceIdToUUID = (traceId: string): string => {\n let id = traceId.toLowerCase();\n if (id.startsWith('0x')) {\n id = id.slice(2);\n }\n if (id.length !== 32) {\n console.warn(`Trace ID ${traceId} is not 32 hex chars long. This is not a valid OpenTelemetry trace ID.`);\n }\n if (!/^[0-9a-f]+$/.test(id)) {\n console.error(`Trace ID ${traceId} is not a valid hex string. Generating a random UUID instead.`);\n return newUUID();\n }\n\n return id.replace(/^(.{8})(.{4})(.{4})(.{4})(.{12})$/, '$1-$2-$3-$4-$5');\n}\n\nexport const uuidToOtelTraceId = (uuid: string): string => {\n return uuid.replace(/-/g, '');\n}\n","import { Laminar } from \"./laminar\";\nimport { EvaluationDatapoint } from \"./types\";\nimport cliProgress from \"cli-progress\";\nimport { EvaluationDataset } from \"./datasets\";\nimport { otelSpanIdToUUID, otelTraceIdToUUID } from \"./utils\";\nimport { observe } from \"./decorators\";\nimport { trace } from \"@opentelemetry/api\";\nimport { SPAN_TYPE } from \"./sdk/tracing/attributes\";\nimport { InitializeOptions } from \"./sdk/interfaces\";\n\nconst DEFAULT_BATCH_SIZE = 5;\n\ndeclare global {\n var _evaluation: Evaluation<any, any, any> | undefined;\n // If true, then we need to set the evaluation globally without running it\n var _set_global_evaluation: boolean;\n}\n\nconst getEvaluationUrl = (projectId: string, evaluationId: string) => {\n return `https://www.lmnr.ai/project/${projectId}/evaluations/${evaluationId}`;\n}\n\nconst getAverageScores =\n <D, T, O>(results: EvaluationDatapoint<D, T, O>[]): Record<string, number> => {\n const perScoreValues: Record<string, number[]> = {};\n for (const result of results) {\n for (const key in result.scores) {\n if (perScoreValues[key]) {\n perScoreValues[key].push(result.scores[key]);\n } else {\n perScoreValues[key] = [result.scores[key]];\n }\n }\n }\n\n const averageScores: Record<string, number> = {};\n for (const key in perScoreValues) {\n averageScores[key] = perScoreValues[key].reduce((a, b) => a + b, 0)\n / perScoreValues[key].length;\n }\n\n return averageScores;\n }\n\n/**\n * Configuration for the Evaluator\n */\ninterface EvaluatorConfig {\n /**\n * The number of data points to evaluate in one batch. This many\n * data points will be evaluated in parallel. Defaults to 5.\n */\n batchSize?: number;\n /**\n * The project API key to use for the evaluation. If not provided,\n * the API key from the environment variable `LMNR_PROJECT_API_KEY` will be used.\n */\n projectApiKey?: string;\n /**\n * The base URL of the Laminar API. If not provided, the default is \n * `https://api.lmnr.ai`. Useful with self-hosted Laminar instances.\n * Do NOT include the port in the URL, use `httpPort` and `grpcPort` instead.\n */\n baseUrl?: string;\n /**\n * The HTTP port of the Laminar API. If not provided, the default is 443.\n */\n httpPort?: number;\n /**\n * The gRPC port of the Laminar API. If not provided, the default is 8443.\n */\n grpcPort?: number;\n /**\n * Object with modules to instrument. If not provided, all\n * available modules are instrumented.\n * See {@link https://docs.lmnr.ai/tracing/automatic-instrumentation}\n */\n instrumentModules?: InitializeOptions['instrumentModules'];\n}\n\n/**\n * Datapoint is a single data point in the evaluation. `D` is the type of the input data,\n * `T` is the type of the target data.\n */\nexport type Datapoint<D, T> = {\n /**\n * input to the executor function. Must be json serializable. Required.\n */\n data: D;\n /**\n * input to the evaluator function (alongside the executor output).\n * Must be json serializable.\n */\n target?: T;\n}\n\ntype EvaluatorFunctionReturn = number | Record<string, number>;\n\n/**\n * EvaluatorFunction is a function that takes the output of the executor and the\n * target data, and returns a score. The score can be a single number or a record\n * of string keys and number values. The latter is useful for evaluating\n * multiple criteria in one go instead of running multiple evaluators.\n */\ntype EvaluatorFunction<O, T> = (output: O, target: T | undefined, ...args: any[]) =>\n EvaluatorFunctionReturn | Promise<EvaluatorFunctionReturn>;\n\n/**\n * HumanEvaluator is an object to register a human evaluator. For now, it only\n * holds the queue name.\n */\nexport class HumanEvaluator {\n private queueName: string;\n\n constructor(queueName: string) {\n this.queueName = queueName;\n }\n}\n\ninterface EvaluationConstructorProps<D, T, O> {\n /**\n * List of data points to evaluate. `data` is the input to the executor function,\n * `target` is the input to the evaluator function.\n */\n data: (Datapoint<D, T>[]) | EvaluationDataset<D, T>;\n /**\n * The executor function. Takes the data point + any additional arguments\n * and returns the output to evaluate.\n */\n executor: (data: D, ...args: any[]) => O | Promise<O>;\n /**\n * Evaluator functions and names. Each evaluator function takes the output of\n * the executor _and_ the target data, and returns a score. The score can be a\n * single number or a dict of string keys and number values. If the score is a\n * single number, it will be named after the evaluator function. Evaluator\n * function names must contain only letters, digits, hyphens, underscores,\n * or spaces.\n */\n evaluators: Record<string, EvaluatorFunction<O, T>>;\n /**\n * [Beta] Array of instances of {@link HumanEvaluator}.\n * For now, HumanEvaluator only holds the queue name.\n */\n humanEvaluators?: HumanEvaluator[];\n /**\n * Name of the evaluation. If not provided, a random name will be assigned.\n */\n name?: string;\n /**\n * Optional group id of the evaluation. Only evaluations within the same\n * group_id can be visually compared. Defaults to \"default\".\n */\n groupId?: string;\n /**\n * Optional override configurations for the evaluator.\n */\n config?: EvaluatorConfig;\n}\n\n/**\n * Reports the whole progress to the console.\n */\nclass EvaluationReporter {\n private cliProgress: cliProgress.SingleBar = new cliProgress.SingleBar(\n {},\n cliProgress.Presets.shades_classic\n );\n private progressCounter: number = 0;\n\n constructor() { }\n\n public start({ length }: { length: number }) {\n this.cliProgress.start(length, 0);\n }\n\n public update(batchLength: number) {\n this.progressCounter += batchLength;\n this.cliProgress.update(this.progressCounter);\n }\n\n // Call either error or stop, not both\n public stopWithError(error: Error) {\n this.cliProgress.stop();\n process.stdout.write(`\\nError: ${error.message}\\n`);\n }\n\n // Call either error or stop, not both\n public stop({\n averageScores,\n projectId,\n evaluationId\n }: { averageScores: Record<string, number>, projectId: string, evaluationId: string }) {\n this.cliProgress.stop();\n process.stdout.write(`\\nCheck results at ${getEvaluationUrl(projectId, evaluationId)}\\n`);\n process.stdout.write('\\nAverage scores:\\n');\n for (const key in averageScores) {\n process.stdout.write(`${key}: ${JSON.stringify(averageScores[key])}\\n`);\n }\n process.stdout.write('\\n');\n }\n}\n\nclass Evaluation<D, T, O> {\n private isFinished: boolean = false;\n private progressReporter: EvaluationReporter;\n private data: Datapoint<D, T>[] | EvaluationDataset<D, T>;\n private executor: (data: D, ...args: any[]) => O | Promise<O>;\n private evaluators: Record<string, EvaluatorFunction<O, T>>;\n private humanEvaluators?: HumanEvaluator[];\n private groupId?: string;\n private name?: string;\n private batchSize: number = DEFAULT_BATCH_SIZE;\n\n constructor({\n data, executor, evaluators, humanEvaluators, groupId, name, config\n }: EvaluationConstructorProps<D, T, O>) {\n if (Object.keys(evaluators).length === 0) {\n throw new Error('No evaluators provided');\n }\n\n const evaluatorNameRegex = /^[\\w\\s-]+$/;\n // Validate evaluator keys\n for (const key in evaluators) {\n if (!evaluatorNameRegex.test(key)) {\n throw new Error(\n `Invalid evaluator key: \"${key}\".` +\n \"Keys must only contain letters, digits, hyphens, underscores, or spaces.\"\n );\n }\n }\n\n this.progressReporter = new EvaluationReporter();\n this.data = data;\n this.executor = executor;\n this.evaluators = evaluators;\n this.humanEvaluators = humanEvaluators;\n this.groupId = groupId;\n this.name = name;\n if (config) {\n this.batchSize = config.batchSize ?? DEFAULT_BATCH_SIZE;\n }\n Laminar.initialize({\n projectApiKey: config?.projectApiKey,\n baseUrl: config?.baseUrl,\n httpPort: config?.httpPort,\n grpcPort: config?.grpcPort,\n instrumentModules: config?.instrumentModules\n });\n }\n\n public async run(): Promise<void> {\n if (this.isFinished) {\n throw new Error('Evaluation is already finished');\n }\n\n this.progressReporter.start({ length: await this.getLength() });\n let resultDatapoints: EvaluationDatapoint<D, T, O>[];\n try {\n resultDatapoints = await this.evaluateInBatches();\n } catch (e) {\n this.progressReporter.stopWithError(e as Error);\n this.isFinished = true;\n return;\n }\n\n const evaluation = await Laminar.createEvaluation({\n groupId: this.groupId,\n name: this.name,\n data: resultDatapoints\n });\n const averageScores = getAverageScores(resultDatapoints);\n this.progressReporter.stop({\n averageScores,\n projectId: evaluation.projectId,\n evaluationId: evaluation.id\n });\n this.isFinished = true;\n\n await Laminar.shutdown();\n }\n\n public async evaluateInBatches(): Promise<EvaluationDatapoint<D, T, O>[]> {\n const resultDatapoints: EvaluationDatapoint<D, T, O>[] = [];\n for (let i = 0; i < await this.getLength(); i += this.batchSize) {\n const batch = await this.data.slice(i, i + this.batchSize);\n const batchDatapoints = await this.evaluateBatch(batch);\n resultDatapoints.push(...batchDatapoints);\n this.progressReporter.update(batch.length);\n }\n return resultDatapoints;\n }\n\n private async evaluateBatch(batch: Datapoint<D, T>[]): Promise<EvaluationDatapoint<D, T, O>[]> {\n const batchPromises = batch.map(async (datapoint) => {\n let ret: EvaluationDatapoint<D, T, O> | undefined;\n\n // NOTE: If you decide to move this observe to another place, note that\n // traceId is assigned inside it for EvaluationDatapoint\n await observe({ name: \"evaluation\", traceType: \"EVALUATION\" }, async () => {\n trace.getActiveSpan()!.setAttribute(SPAN_TYPE, \"EVALUATION\");\n\n const { output, executorSpanId } = await observe(\n { name: \"executor\" },\n async (data: D) => {\n const executorSpanId = trace.getActiveSpan()!.spanContext().spanId;\n trace.getActiveSpan()!.setAttribute(SPAN_TYPE, \"EXECUTOR\");\n return {\n output: await this.executor(data),\n executorSpanId: otelSpanIdToUUID(executorSpanId)\n };\n },\n datapoint.data\n );\n const target = datapoint.target;\n\n let scores: Record<string, number> = {};\n for (const [evaluatorName, evaluator] of Object.entries(this.evaluators)) {\n const value = await observe(\n { name: evaluatorName },\n async (output: O, target?: T) => {\n trace.getActiveSpan()!.setAttribute(SPAN_TYPE, \"EVALUATOR\");\n return await evaluator(output, target);\n },\n output,\n target\n );\n\n if (typeof value === 'number') {\n if (isNaN(value)) {\n throw new Error(`Evaluator ${evaluatorName} returned NaN`);\n }\n scores[evaluatorName] = value;\n } else {\n scores = { ...scores, ...value };\n }\n }\n\n ret = {\n executorOutput: output,\n data: datapoint.data,\n target,\n scores,\n traceId: otelTraceIdToUUID(trace.getActiveSpan()!.spanContext().traceId),\n // For now, all human evaluators are added to every datapoint\n // In the future, we will allow to specify which evaluators are\n // added to a particular datapoint, e.g. random sampling.\n humanEvaluators: this.humanEvaluators,\n executorSpanId\n } as EvaluationDatapoint<D, T, O>;\n });\n\n return ret!;\n });\n\n const results = await Promise.all(batchPromises);\n\n return results;\n }\n\n private async getLength(): Promise<number> {\n return this.data instanceof EvaluationDataset ? await this.data.size() : this.data.length;\n }\n}\n\n/**\n * If added to the file which is called through lmnr eval command, then simply\n * registers the evaluation. Otherwise, returns a promise which resolves when\n * the evaluation is finished. If the evaluation has no async logic, then it\n * will be executed synchronously.\n *\n * @param props.data List of data points to evaluate. `data` is the input to the\n * executor function, `target` is the input to the evaluator function.\n * @param props.executor The executor function. Takes the data point + any\n * additional arguments and returns the output to evaluate.\n * @param props.evaluators Map from evaluator name to evaluator function. Each\n * evaluator function takes the output of the executor and the target data, and\n * returns.\n * @param props.humanEvaluators [Beta] Array of instances of {@link HumanEvaluator}.\n * For now, HumanEvaluator only holds the queue name.\n * @param props.groupId Group name which is same as the feature you are evaluating\n * in your project or application. Defaults to \"default\".\n * @param props.name Optional name of the evaluation. Used to easily identify\n * the evaluation in the group.\n * @param props.config Optional override configurations for the evaluator.\n */\nexport async function evaluate<D, T, O>({\n data, executor, evaluators, humanEvaluators, groupId, name, config\n}: EvaluationConstructorProps<D, T, O>): Promise<void> {\n const evaluation = new Evaluation({\n data,\n executor,\n evaluators,\n humanEvaluators,\n name,\n groupId,\n config\n });\n if (globalThis._set_global_evaluation) {\n globalThis._evaluation = evaluation;\n } else {\n await evaluation.run();\n }\n}\n","import { Datapoint } from './evaluations';\nimport { Laminar as L } from './laminar';\n\nconst DEFAULT_FETCH_SIZE = 25;\n\nexport abstract class EvaluationDataset<D, T> {\n public async slice(start: number, end: number): Promise<Datapoint<D, T>[]> {\n const result = [];\n for (let i = Math.max(start, 0); i < Math.min(end, await this.size()); i++) {\n result.push(await this.get(i));\n }\n return result;\n }\n public abstract size(): Promise<number> | number;\n public abstract get(index: number): Promise<Datapoint<D, T>> | Datapoint<D, T>;\n}\n\nexport class LaminarDataset<D, T> extends EvaluationDataset<D, T> {\n private fetchedItems: Datapoint<D, T>[] = [];\n private len: number | null = null;\n private offset: number = 0;\n private fetchSize: number;\n private name: string;\n\n constructor(name: string, fetchSize?: number) {\n super();\n this.name = name;\n this.fetchSize = fetchSize || DEFAULT_FETCH_SIZE;\n }\n\n private async fetchBatch() {\n // Commented out until we allow users to set log level\n // console.debug(`Dataset ${this.name}. Fetching batch from ${this.offset} to ${this.offset + this.fetchSize}`);\n const resp = await L.getDatapoints<D, T>({\n datasetName: this.name,\n offset: this.offset,\n limit: this.fetchSize,\n });\n this.fetchedItems = this.fetchedItems.concat(resp.items);\n this.offset = this.fetchedItems.length;\n if (this.len === null) {\n this.len = resp.totalCount;\n }\n }\n\n public async size(): Promise<number> {\n if (this.len === null) {\n await this.fetchBatch();\n }\n return this.len!;\n }\n public async get(index: number): Promise<Datapoint<D, T>> {\n if (index >= this.fetchedItems.length) {\n await this.fetchBatch();\n }\n return this.fetchedItems[index];\n }\n}\n","import { withEntity } from './sdk/node-server-sdk'\nimport { Laminar } from './laminar';\nimport { TraceType } from './types';\n\ninterface ObserveOptions {\n name?: string;\n sessionId?: string;\n userId?: string;\n traceType?: TraceType;\n spanType?: 'DEFAULT' | 'LLM';\n traceId?: string;\n}\n\n/**\n * The main decorator entrypoint for Laminar. This is used to wrap\n * functions and methods to create spans.\n *\n * @param name - Name of the span. Function name is used if not specified.\n * @param userId - User ID to associate with the span and the following context.\n * @param sessionId - Session ID to associate with the span and the following context.\n * @param traceType – Type of the trace. Unless it is within evaluation, it should be 'DEFAULT'.\n * @param spanType - Type of the span. 'DEFAULT' is used if not specified. If the type is 'LLM',\n * you must manually specify some attributes. See {@link Laminar.setSpanAttributes} for more\n * information.\n * @returns Returns the result of the wrapped function.\n * @throws Exception - Re-throws the exception if the wrapped function throws an exception.\n * \n * @example\n * ```typescript\n * import { observe } from '@lmnr-ai/lmnr';\n * \n * await observe({ name: 'my_function' }, () => {\n * // Your code here\n * });\n */\nexport async function observe<A extends unknown[], F extends (...args: A) => ReturnType<F>>(\n {\n name,\n sessionId,\n userId,\n traceType,\n spanType,\n traceId,\n }: ObserveOptions, fn: F, ...args: A): Promise<ReturnType<F>> {\n let associationProperties = {};\n if (sessionId) {\n associationProperties = { ...associationProperties, \"session_id\": sessionId };\n }\n if (userId) {\n associationProperties = { ...associationProperties, \"user_id\": userId };\n }\n if (traceType) {\n associationProperties = { ...associationProperties, \"trace_type\": traceType };\n }\n if (spanType) {\n associationProperties = { ...associationProperties, \"span_type\": spanType };\n }\n\n return await withEntity<A, F>({\n name: name ?? fn.name,\n associationProperties,\n traceId\n }, fn, undefined, ...args);\n}\n"],"mappings":"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","names":["import_api","import_api","import_api","import_api","import_core","uuidv4","import_sdk_trace_base","contextApi","context","import_api","cliProgress","executorSpanId","output","target","import_api"]}
|
|
1
|
+
{"version":3,"sources":["../src/index.ts","../src/laminar.ts","../src/sdk/errors/index.ts","../src/sdk/tracing/index.ts","../src/sdk/tracing/tracing.ts","../src/sdk/tracing/attributes.ts","../src/sdk/configuration/index.ts","../src/sdk/tracing/decorators.ts","../src/utils.ts","../src/evaluations.ts","../src/datasets.ts","../src/decorators.ts"],"sourcesContent":["export {\n NodeInput,\n PipelineRunResponse,\n PipelineRunRequest,\n ChatMessage,\n Event,\n EvaluateEvent,\n} from './types';\n\nexport { Laminar } from './laminar';\nexport { evaluate, Datapoint, HumanEvaluator } from './evaluations';\nexport { EvaluationDataset as Dataset, LaminarDataset } from './datasets';\nexport { observe, withLabels } from './decorators';\nexport { LaminarAttributes } from './sdk/tracing/attributes';\nexport { Span } from '@opentelemetry/api';\n","import {\n PipelineRunResponse,\n PipelineRunRequest,\n EvaluationDatapoint,\n CreateEvaluationResponse,\n GetDatapointsResponse\n} from './types';\nimport {\n Attributes,\n AttributeValue,\n Context,\n context as contextApi,\n isSpanContextValid,\n Span,\n TimeInput,\n trace,\n TraceFlags\n} from '@opentelemetry/api';\nimport { InitializeOptions, initialize as traceloopInitialize } from './sdk/node-server-sdk'\nimport { isStringUUID, otelSpanIdToUUID, otelTraceIdToUUID, uuidToOtelTraceId } from './utils';\nimport { OTLPTraceExporter } from '@opentelemetry/exporter-trace-otlp-grpc';\nimport { Metadata } from '@grpc/grpc-js';\nimport { ASSOCIATION_PROPERTIES_KEY, getSpanPath, getTracer, SPAN_PATH_KEY } from './sdk/tracing/tracing';\nimport { forceFlush } from './sdk/node-server-sdk';\nimport {\n ASSOCIATION_PROPERTIES,\n OVERRIDE_PARENT_SPAN,\n SESSION_ID,\n SPAN_INPUT,\n SPAN_OUTPUT,\n SPAN_PATH,\n SPAN_TYPE,\n USER_ID,\n LaminarAttributes,\n} from './sdk/tracing/attributes';\nimport { RandomIdGenerator } from '@opentelemetry/sdk-trace-base';\n\n\ninterface LaminarInitializeProps {\n projectApiKey?: string;\n env?: Record<string, string>;\n baseUrl?: string;\n httpPort?: number;\n grpcPort?: number;\n instrumentModules?: InitializeOptions[\"instrumentModules\"];\n}\n\nexport class Laminar {\n private static baseHttpUrl: string;\n private static baseGrpcUrl: string;\n private static projectApiKey: string;\n private static env: Record<string, string> = {};\n private static isInitialized: boolean = false;\n\n /**\n * Initialize Laminar context across the application.\n * This method must be called before using any other Laminar methods or decorators.\n *\n * @param project_api_key - Laminar project api key. You can generate one by going\n * to the projects settings page on the Laminar dashboard.\n * If not specified, it will try to read from the LMNR_PROJECT_API_KEY environment variable.\n * @param env - Default environment passed to `run` requests, unless overriden at request\n * time. Usually, model provider keys are stored here.\n * @param baseUrl - Laminar API url. Do not include the port, use\n * `httpPort` and `grpcPort` instead.\n * If not specified, defaults to https://api.lmnr.ai.\n * @param httpPort - Laminar API http port.\n * If not specified, defaults to 443.\n * @param grpcPort - Laminar API grpc port.\n * If not specified, defaults to 8443.\n * @param instrumentModules - List of modules to instrument.\n * If not specified, all auto-instrumentable modules will be instrumented, which include\n * LLM calls (OpenAI, Anthropic, etc), Langchain, VectorDB calls (Pinecone, Qdrant, etc).\n * Pass an empty object {} to disable any kind of automatic instrumentation.\n * If you only want to auto-instrument specific modules, then pass them in the object.\n * \n * @example\n * import { Laminar as L } from '@lmnr-ai/lmnr';\n * import { OpenAI } from 'openai';\n * import * as ChainsModule from \"langchain/chains\";\n * \n * // Initialize Laminar while auto-instrumenting Langchain and OpenAI modules.\n * L.initialize({ projectApiKey: \"<LMNR_PROJECT_API_KEY>\", instrumentModules: {\n * langchain: {\n * chainsModule: ChainsModule\n * },\n * openAI: OpenAI\n * } });\n *\n * @throws {Error} - If project API key is not set\n */\n public static initialize({\n projectApiKey,\n env,\n baseUrl,\n httpPort,\n grpcPort,\n instrumentModules\n }: LaminarInitializeProps) {\n\n let key = projectApiKey ?? process.env.LMNR_PROJECT_API_KEY;\n if (key === undefined) {\n throw new Error(\n 'Please initialize the Laminar object with your project API key ' +\n 'or set the LMNR_PROJECT_API_KEY environment variable'\n );\n }\n this.projectApiKey = key;\n if (baseUrl?.match(/:\\d{1,5}$/g)) {\n throw new Error(\n 'Port should be passed separately in `httpPort` and `grpcPort`'\n );\n }\n\n this.baseHttpUrl = `${baseUrl ?? 'https://api.lmnr.ai'}:${httpPort ?? 443}`;\n this.baseGrpcUrl = `${baseUrl ?? 'https://api.lmnr.ai'}:${grpcPort ?? 8443}`;\n\n this.isInitialized = true;\n this.env = env ?? {};\n\n const metadata = new Metadata();\n metadata.set('authorization', `Bearer ${this.projectApiKey}`);\n const exporter = new OTLPTraceExporter({\n url: this.baseGrpcUrl,\n metadata,\n });\n\n traceloopInitialize({\n exporter,\n silenceInitializationMessage: true,\n instrumentModules,\n disableBatch: false,\n });\n }\n\n /**\n * Check if Laminar has been initialized. Utility to make sure other methods\n * are called after initialization.\n */\n public static initialized(): boolean {\n return this.isInitialized;\n }\n\n /**\n * Sets the environment that will be sent to Laminar requests.\n * \n * @param env - The environment variables to override. If not provided, the\n * current environment will not be modified.\n */\n public static setEnv(env?: Record<string, string>) {\n if (env) {\n this.env = env;\n }\n }\n\n /**\n * Sets the project API key for authentication with Laminar.\n *\n * @param projectApiKey - The API key to be set. If not provided, the existing\n * API key will not be modified.\n */\n public static setProjectApiKey(projectApiKey?: string) {\n if (projectApiKey) {\n this.projectApiKey = projectApiKey;\n }\n }\n\n /**\n * Runs the pipeline with the given inputs\n *\n * @param pipeline - The name of the Laminar pipeline. Pipeline must have a target version.\n * @param inputs - The inputs for the pipeline. Map from an input node name to input data.\n * @param env - The environment variables for the pipeline execution.\n * Typically used for model provider keys.\n * @param metadata - Additional metadata for the pipeline run.\n * @param currentSpanId - The ID of the current span.\n * @param currentTraceId - The ID of the current trace.\n * @returns A promise that resolves to the response of the pipeline run.\n * @throws An error if the Laminar object is not initialized with a project API\n * key or if the request fails.\n */\n public static async run({\n pipeline,\n inputs,\n env,\n metadata = {},\n currentSpanId,\n currentTraceId,\n }: PipelineRunRequest): Promise<PipelineRunResponse> {\n const currentSpan = trace.getActiveSpan();\n let parentSpanId: string | undefined;\n let traceId: string | undefined;\n if (currentSpan !== undefined && isSpanContextValid(currentSpan.spanContext())) {\n parentSpanId = currentSpanId ?? otelSpanIdToUUID(currentSpan.spanContext().spanId);\n traceId = currentTraceId ?? otelTraceIdToUUID(currentSpan.spanContext().traceId);\n } else {\n parentSpanId = currentSpanId;\n traceId = currentTraceId;\n }\n if (this.projectApiKey === undefined) {\n throw new Error(\n 'Please initialize the Laminar object with your project API key ' +\n 'or set the LMNR_PROJECT_API_KEY environment variable'\n );\n }\n const envirionment = env === undefined ? this.env : env;\n\n const response = await fetch(`${this.baseHttpUrl}/v1/pipeline/run`, {\n method: 'POST',\n headers: this.getHeaders(),\n body: JSON.stringify({\n inputs,\n pipeline,\n env: envirionment,\n metadata,\n parentSpanId,\n traceId,\n })\n });\n\n if (!response.ok) {\n throw new Error(`Failed to run pipeline ${pipeline}. Response: ${response.statusText}`);\n }\n try {\n return await response.json() as PipelineRunResponse;\n } catch (error) {\n throw new Error(`Failed to parse response from pipeline ${pipeline}. Error: ${error}`);\n }\n }\n\n /**\n * Associates an event with the current span. If event with such name never\n * existed, Laminar will create a new event and infer its type from the value.\n * If the event already exists, Laminar will append the value to the event\n * if and only if the value is of a matching type. Otherwise, the event won't\n * be recorded. Supported types are string, number, and boolean. If the value\n * is `null`, event is considered a boolean tag with the value of `true`.\n *\n * @param name - The name of the event.\n * @param value - The value of the event. Must be a primitive type. If not\n * specified, boolean true is assumed in the backend.\n * @param timestamp - The timestamp of the event. If not specified, relies on\n * the underlying OpenTelemetry implementation.\n * If specified as an integer, it must be epoch nanoseconds.\n */\n public static event(\n name: string,\n value?: AttributeValue,\n timestamp?: TimeInput,\n ) {\n const currentSpan = trace.getActiveSpan();\n if (currentSpan === undefined || !isSpanContextValid(currentSpan.spanContext())) {\n console.warn(\"Laminar().event()\\` called outside of span context.\" +\n ` Event '${name}' will not be recorded in the trace.` +\n \" Make sure to annotate the function with a decorator\"\n );\n return;\n }\n\n const event: Attributes = {\n \"lmnr.event.type\": \"default\",\n }\n if (value !== undefined) {\n event[\"lmnr.event.value\"] = value;\n }\n\n currentSpan.addEvent(name, event, timestamp);\n }\n\n /**\n * Sets the session information for the current span and returns the\n * context to use for the following spans.\n * \n * @param sessionId - The session ID to associate with the context.\n * @param userId - The user ID to associate with the context.\n * @returns The updated context with the association properties.\n * \n * @example\n * import { context as contextApi } from '@opentelemetry/api';\n * import { Laminar } from '@lmnr-ai/laminar';\n * const context = Laminar.contextWithSession({ sessionId: \"1234\", userId: \"5678\" });\n * contextApi.with(context, () => {\n * // Your code here\n * });\n */\n public static contextWithSession({\n sessionId,\n userId\n }: { sessionId?: string, userId?: string }): Context {\n const currentSpan = trace.getActiveSpan();\n if (currentSpan !== undefined && isSpanContextValid(currentSpan.spanContext())) {\n if (sessionId) {\n currentSpan.setAttribute(SESSION_ID, sessionId);\n }\n if (userId) {\n currentSpan.setAttribute(USER_ID, userId);\n }\n }\n let associationProperties = {};\n if (sessionId) {\n associationProperties = { ...associationProperties, \"session_id\": sessionId };\n }\n if (userId) {\n associationProperties = { ...associationProperties, \"user_id\": userId };\n }\n\n let entityContext = contextApi.active();\n const currentAssociationProperties = entityContext.getValue(ASSOCIATION_PROPERTIES_KEY);\n if (associationProperties) {\n entityContext = entityContext.setValue(\n ASSOCIATION_PROPERTIES_KEY,\n { ...(currentAssociationProperties ?? {}), ...associationProperties },\n );\n }\n\n return entityContext;\n }\n\n /**\n * Set attributes for the current span. Useful for manual\n * instrumentation.\n * @param attributes - The attributes to set for the current span.\n * \n * @example\n * import { Laminar as L, observe } from '@lmnr-ai/laminar';\n * await observe({ name: 'mySpanName', spanType: 'LLM' }, async (msg: string) => {\n * const response = await myCustomCallToOpenAI(msg);\n * L.setSpanAttributes({\n * [LaminarAttributes.PROVIDER]: 'openai',\n * [LaminarAttributes.REQUEST_MODEL]: \"requested_model\",\n * [LaminarAttributes.RESPONSE_MODEL]: response.model,\n * [LaminarAttributes.INPUT_TOKEN_COUNT]: response.usage.prompt_tokens,\n * [LaminarAttributes.OUTPUT_TOKEN_COUNT]: response.usage.completion_tokens,\n * })\n * }, userMessage);\n */\n public static setSpanAttributes(\n attributes: Record<typeof LaminarAttributes[keyof typeof LaminarAttributes], AttributeValue>\n ) {\n const currentSpan = trace.getActiveSpan();\n if (currentSpan !== undefined && isSpanContextValid(currentSpan.spanContext())) {\n for (const [key, value] of Object.entries(attributes)) {\n currentSpan.setAttribute(key, value);\n }\n }\n }\n\n /**\n * Set the output of the current span. Useful for manual instrumentation.\n * @param output - Output of the span. Will be sent as an attribute, so must be serializable to JSON.\n */\n public static setSpanOutput(output: any) {\n if (output == null) {\n return;\n }\n const currentSpan = trace.getActiveSpan();\n if (currentSpan !== undefined && isSpanContextValid(currentSpan.spanContext())) {\n currentSpan.setAttribute(SPAN_OUTPUT, JSON.stringify(output));\n }\n }\n\n /**\n * Start a new span, but don't set it as active. Useful for\n * manual instrumentation. If span type is 'LLM', you should report usage\n * manually. See {@link setSpanAttributes} for more information.\n * \n * @param name - name of the span\n * @param input - input to the span. Will be sent as an attribute, so must\n * be JSON serializable\n * @param span_type - type of the span. Defaults to 'DEFAULT'\n * @param context - raw OpenTelemetry context to bind the span to.\n * @param traceId - [EXPERIMENTAL] override the trace id for the span. If not\n * provided, uses the current trace id.\n * @returns The started span.\n * \n * @example\n * import { Laminar, observe } from '@lmnr-ai/lmnr';\n * const foo = async (span: Span) => {\n * await Laminar.withSpan(span, async () => {\n * await observe({ name: 'foo' }, async () => {\n * // Your code here\n * })\n * })\n * };\n * const bar = async (span: Span) => {\n * await Laminar.withSpan(span, async () => {\n * await openai_client.chat.completions.create();\n * })\n * };\n * \n * const parentSpan = Laminar.startSpan({name: \"outer\"});\n * foo(parentSpan);\n * await bar(parentSpan);\n * // IMPORTANT: Don't forget to end the span!\n * parentSpan.end();\n * \n * // Results in:\n * // | outer\n * // | | foo\n * // | | | ...\n * // | | bar\n * // | | | openai.chat\n */\n public static startSpan({\n name,\n input,\n spanType,\n context,\n traceId,\n labels,\n }: {\n name: string,\n input?: any,\n spanType?: 'LLM' | 'DEFAULT',\n context?: Context,\n traceId?: string,\n labels?: Record<string, string>,\n }): Span {\n let entityContext = context ?? contextApi.active();\n const currentSpanPath = getSpanPath(entityContext);\n const spanPath = currentSpanPath ? `${currentSpanPath}.${name}` : name;\n entityContext = entityContext.setValue(SPAN_PATH_KEY, spanPath);\n if (traceId) {\n if (isStringUUID(traceId)) {\n const spanContext = {\n traceId: uuidToOtelTraceId(traceId),\n spanId: new RandomIdGenerator().generateSpanId(),\n traceFlags: TraceFlags.SAMPLED,\n isRemote: false,\n };\n entityContext = trace.setSpanContext(entityContext, spanContext);\n } else {\n console.warn(`Invalid trace ID ${traceId}. Expected a UUID.`);\n }\n }\n const labelProperties = labels ? Object.entries(labels).reduce((acc, [key, value]) => {\n acc[`${ASSOCIATION_PROPERTIES}.label.${key}`] = value;\n return acc;\n }, {} as Record<string, string>) : {};\n const attributes = {\n [SPAN_TYPE]: spanType ?? 'DEFAULT',\n [SPAN_PATH]: spanPath,\n ...labelProperties,\n }\n const span = getTracer().startSpan(name, { attributes }, entityContext);\n if (traceId) {\n span.setAttribute(OVERRIDE_PARENT_SPAN, true);\n }\n if (input) {\n span.setAttribute(SPAN_INPUT, JSON.stringify(input));\n }\n return span;\n }\n\n /**\n * A utility wrapper around OpenTelemetry's `context.with()`. Useful for \n * passing spans around in manual instrumentation:\n * \n * @param span - Parent span to bind the execution to.\n * @param fn - Function to execute within the span context.\n * @param endOnExit - Whether to end the span after the function has\n * executed. Defaults to `false`. If `false`, you MUST manually call\n * `span.end()` at the end of the execution, so that spans are not lost.\n * @returns The result of the function execution.\n * \n * See {@link startSpan} docs for a usage example\n */\n public static withSpan<T>(span: Span, fn: () => T, endOnExit?: boolean): T {\n return contextApi.with(trace.setSpan(contextApi.active(), span), () => {\n try{\n const result = fn();\n return result;\n }\n finally {\n if (endOnExit !== undefined && endOnExit) {\n span.end();\n }\n }\n });\n }\n\n public static async shutdown() {\n await forceFlush();\n }\n\n public static async createEvaluation<D, T, O>({\n groupId,\n name,\n data\n }: {\n groupId?: string,\n name?: string,\n data: EvaluationDatapoint<D, T, O>[]\n }): Promise<CreateEvaluationResponse> {\n let body = '';\n try {\n body = JSON.stringify({\n groupId: groupId ?? null,\n name: name ?? null,\n points: data,\n });\n } catch (error) {\n throw new Error(`Failed to serialize evaluation data for ${name}. Error: ${error}`);\n }\n const response = await fetch(`${this.baseHttpUrl}/v1/evaluations`, {\n method: 'POST',\n headers: this.getHeaders(),\n body,\n });\n\n if (!response.ok) {\n throw new Error(`Failed to create evaluation ${name}. Response: ${response.statusText}`);\n }\n\n return await response.json() as CreateEvaluationResponse;\n }\n\n public static async getDatapoints<D, T>({\n datasetName,\n offset,\n limit,\n }: {\n datasetName: string,\n offset: number,\n limit: number,\n }): Promise<GetDatapointsResponse<D, T>> {\n const params = new URLSearchParams({\n name: datasetName,\n offset: offset.toString(),\n limit: limit.toString()\n });\n const response = await fetch(`${this.baseHttpUrl}/v1/datasets/datapoints?${params.toString()}`, {\n method: 'GET',\n headers: this.getHeaders(),\n });\n\n if (!response.ok) {\n throw new Error(`Failed to get datapoints for dataset ${datasetName}. Response: ${response.statusText}`);\n }\n\n return await response.json() as GetDatapointsResponse<D, T>;\n }\n\n private static getHeaders() {\n return {\n \"Content-Type\": \"application/json\",\n \"Authorization\": `Bearer ${this.projectApiKey}`,\n };\n };\n}\n","/**\n * The severity of an error.\n */\nexport const SEVERITY = {\n Warning: \"Warning\",\n Error: \"Error\",\n Critical: \"Critical\",\n} as const;\n\nexport type Severity = (typeof SEVERITY)[keyof typeof SEVERITY];\n\n/**\n * Base class for all Traceloop errors.\n */\nexport class TraceloopError extends Error {\n /**\n * The severity of the error.\n */\n severity: Severity;\n /**\n * The underlying cause of the error.\n */\n underlyingCause?: Error;\n\n constructor(message: string, severity: Severity = SEVERITY.Error) {\n super(message);\n this.severity = severity;\n }\n}\n\nexport class NotInitializedError extends TraceloopError {\n constructor() {\n super(\n `The Traceloop SDK must be initialized by calling the \"initialize\" function prior to use.`,\n SEVERITY.Critical,\n );\n }\n}\n\nexport class InitializationError extends TraceloopError {\n constructor(message?: string, cause?: Error) {\n super(message ?? \"Failed to initialize Traceloop SDK\", SEVERITY.Critical);\n this.underlyingCause = cause;\n }\n}\n\nexport class ArgumentNotProvidedError extends TraceloopError {\n constructor(argumentName: string) {\n super(`The \"${argumentName}\" argument is required and must be a string.`);\n }\n}\n\nexport class PromptNotFoundError extends TraceloopError {\n constructor(key: string) {\n super(`The prompt \"${key}\" was not found in the registry.`);\n }\n}\n","/* eslint-disable @typescript-eslint/no-var-requires */\nimport { baggageUtils } from \"@opentelemetry/core\";\nimport { Span, context, diag } from \"@opentelemetry/api\";\nimport { OTLPTraceExporter } from \"@opentelemetry/exporter-trace-otlp-proto\";\nimport { Instrumentation } from \"@opentelemetry/instrumentation\";\nimport { InitializeOptions } from \"../interfaces\";\nimport {\n ASSOCIATION_PROPERTIES_KEY,\n SPAN_PATH_KEY,\n} from \"./tracing\";\nimport { _configuration } from \"../configuration\";\nimport { NodeTracerProvider, SimpleSpanProcessor, BatchSpanProcessor } from \"@opentelemetry/sdk-trace-node\";\nimport { registerInstrumentations } from \"@opentelemetry/instrumentation\";\nimport { AnthropicInstrumentation } from \"@traceloop/instrumentation-anthropic\";\nimport { OpenAIInstrumentation } from \"@traceloop/instrumentation-openai\";\nimport { AzureOpenAIInstrumentation } from \"@traceloop/instrumentation-azure\";\nimport { LlamaIndexInstrumentation } from \"@traceloop/instrumentation-llamaindex\";\nimport {\n AIPlatformInstrumentation,\n VertexAIInstrumentation,\n} from \"@traceloop/instrumentation-vertexai\";\nimport { BedrockInstrumentation } from \"@traceloop/instrumentation-bedrock\";\nimport { CohereInstrumentation } from \"@traceloop/instrumentation-cohere\";\nimport { PineconeInstrumentation } from \"@traceloop/instrumentation-pinecone\";\nimport { LangChainInstrumentation } from \"@traceloop/instrumentation-langchain\";\nimport { ChromaDBInstrumentation } from \"@traceloop/instrumentation-chromadb\";\nimport { QdrantInstrumentation } from \"@traceloop/instrumentation-qdrant\";\nimport { ASSOCIATION_PROPERTIES, ASSOCIATION_PROPERTIES_OVERRIDES, SPAN_INSTRUMENTATION_SOURCE, SPAN_PATH } from \"./attributes\";\n\nlet _spanProcessor: SimpleSpanProcessor | BatchSpanProcessor;\nlet openAIInstrumentation: OpenAIInstrumentation | undefined;\nlet anthropicInstrumentation: AnthropicInstrumentation | undefined;\nlet azureOpenAIInstrumentation: AzureOpenAIInstrumentation | undefined;\nlet cohereInstrumentation: CohereInstrumentation | undefined;\nlet vertexaiInstrumentation: VertexAIInstrumentation | undefined;\nlet aiplatformInstrumentation: AIPlatformInstrumentation | undefined;\nlet bedrockInstrumentation: BedrockInstrumentation | undefined;\nlet langchainInstrumentation: LangChainInstrumentation | undefined;\nlet llamaIndexInstrumentation: LlamaIndexInstrumentation | undefined;\nlet pineconeInstrumentation: PineconeInstrumentation | undefined;\nlet chromadbInstrumentation: ChromaDBInstrumentation | undefined;\nlet qdrantInstrumentation: QdrantInstrumentation | undefined;\n\n\nconst instrumentations: Instrumentation[] = [];\n\nconst initInstrumentations = () => {\n const enrichTokens = false;\n\n openAIInstrumentation = new OpenAIInstrumentation({\n enrichTokens,\n });\n instrumentations.push(openAIInstrumentation);\n\n anthropicInstrumentation = new AnthropicInstrumentation();\n instrumentations.push(anthropicInstrumentation);\n\n azureOpenAIInstrumentation = new AzureOpenAIInstrumentation();\n instrumentations.push(azureOpenAIInstrumentation);\n\n cohereInstrumentation = new CohereInstrumentation();\n instrumentations.push(cohereInstrumentation);\n\n vertexaiInstrumentation = new VertexAIInstrumentation();\n instrumentations.push(vertexaiInstrumentation);\n\n aiplatformInstrumentation = new AIPlatformInstrumentation();\n instrumentations.push(aiplatformInstrumentation);\n\n bedrockInstrumentation = new BedrockInstrumentation();\n instrumentations.push(bedrockInstrumentation);\n\n pineconeInstrumentation = new PineconeInstrumentation();\n instrumentations.push(pineconeInstrumentation);\n\n langchainInstrumentation = new LangChainInstrumentation();\n instrumentations.push(langchainInstrumentation);\n\n llamaIndexInstrumentation = new LlamaIndexInstrumentation();\n instrumentations.push(llamaIndexInstrumentation);\n\n chromadbInstrumentation = new ChromaDBInstrumentation();\n instrumentations.push(chromadbInstrumentation);\n\n qdrantInstrumentation = new QdrantInstrumentation();\n instrumentations.push(qdrantInstrumentation);\n};\n\nconst manuallyInitInstrumentations = (\n instrumentModules: InitializeOptions[\"instrumentModules\"],\n) => {\n const enrichTokens = false;\n\n instrumentations.length = 0;\n\n if (instrumentModules?.openAI) {\n openAIInstrumentation = new OpenAIInstrumentation({\n enrichTokens,\n });\n instrumentations.push(openAIInstrumentation);\n openAIInstrumentation.manuallyInstrument(instrumentModules.openAI);\n }\n\n if (instrumentModules?.anthropic) {\n anthropicInstrumentation = new AnthropicInstrumentation();\n instrumentations.push(anthropicInstrumentation);\n anthropicInstrumentation.manuallyInstrument(instrumentModules.anthropic);\n }\n\n if (instrumentModules?.azureOpenAI) {\n const instrumentation = new AzureOpenAIInstrumentation();\n instrumentations.push(instrumentation as Instrumentation);\n azureOpenAIInstrumentation = instrumentation;\n instrumentation.manuallyInstrument(instrumentModules.azureOpenAI);\n }\n\n if (instrumentModules?.cohere) {\n cohereInstrumentation = new CohereInstrumentation();\n instrumentations.push(cohereInstrumentation);\n cohereInstrumentation.manuallyInstrument(instrumentModules.cohere);\n }\n\n if (instrumentModules?.google_vertexai) {\n vertexaiInstrumentation = new VertexAIInstrumentation();\n instrumentations.push(vertexaiInstrumentation);\n vertexaiInstrumentation.manuallyInstrument(\n instrumentModules.google_vertexai,\n );\n }\n\n if (instrumentModules?.google_aiplatform) {\n aiplatformInstrumentation = new AIPlatformInstrumentation();\n instrumentations.push(aiplatformInstrumentation);\n aiplatformInstrumentation.manuallyInstrument(\n instrumentModules.google_aiplatform,\n );\n }\n\n if (instrumentModules?.bedrock) {\n bedrockInstrumentation = new BedrockInstrumentation();\n instrumentations.push(bedrockInstrumentation);\n bedrockInstrumentation.manuallyInstrument(instrumentModules.bedrock);\n }\n\n if (instrumentModules?.pinecone) {\n const instrumentation = new PineconeInstrumentation();\n instrumentations.push(instrumentation as Instrumentation);\n instrumentation.manuallyInstrument(instrumentModules.pinecone);\n }\n\n if (instrumentModules?.langchain) {\n langchainInstrumentation = new LangChainInstrumentation();\n instrumentations.push(langchainInstrumentation);\n langchainInstrumentation.manuallyInstrument(instrumentModules.langchain);\n }\n\n if (instrumentModules?.llamaIndex) {\n llamaIndexInstrumentation = new LlamaIndexInstrumentation();\n instrumentations.push(llamaIndexInstrumentation);\n llamaIndexInstrumentation.manuallyInstrument(instrumentModules.llamaIndex);\n }\n\n if (instrumentModules?.chromadb) {\n chromadbInstrumentation = new ChromaDBInstrumentation();\n instrumentations.push(chromadbInstrumentation);\n chromadbInstrumentation.manuallyInstrument(instrumentModules.chromadb);\n }\n\n if (instrumentModules?.qdrant) {\n qdrantInstrumentation = new QdrantInstrumentation();\n instrumentations.push(qdrantInstrumentation);\n qdrantInstrumentation.manuallyInstrument(instrumentModules.qdrant);\n }\n};\n\n/**\n * Initializes the Traceloop SDK.\n * Must be called once before any other SDK methods.\n *\n * @param options - The options to initialize the SDK. See the {@link InitializeOptions} for details.\n */\nexport const startTracing = (options: InitializeOptions) => {\n if (options.instrumentModules !== undefined) {\n // If options.instrumentModules is empty, it will not initialize anything,\n // so empty dict can essentially be passed to disable any kind of automatic instrumentation.\n manuallyInitInstrumentations(options.instrumentModules);\n } else {\n initInstrumentations();\n }\n\n if (!shouldSendTraces()) {\n openAIInstrumentation?.setConfig({\n traceContent: false,\n });\n azureOpenAIInstrumentation?.setConfig({\n traceContent: false,\n });\n llamaIndexInstrumentation?.setConfig({\n traceContent: false,\n });\n vertexaiInstrumentation?.setConfig({\n traceContent: false,\n });\n aiplatformInstrumentation?.setConfig({\n traceContent: false,\n });\n bedrockInstrumentation?.setConfig({\n traceContent: false,\n });\n cohereInstrumentation?.setConfig({\n traceContent: false,\n });\n chromadbInstrumentation?.setConfig({\n traceContent: false,\n });\n }\n\n const headers = process.env.TRACELOOP_HEADERS\n ? baggageUtils.parseKeyPairsIntoRecord(process.env.TRACELOOP_HEADERS)\n : { Authorization: `Bearer ${options.apiKey}` };\n\n const traceExporter =\n options.exporter ??\n new OTLPTraceExporter({\n url: `${options.baseUrl}/v1/traces`,\n headers,\n });\n _spanProcessor = options.disableBatch\n ? new SimpleSpanProcessor(traceExporter)\n : new BatchSpanProcessor(traceExporter);\n\n _spanProcessor.onStart = (span: Span) => {\n const spanPath = context.active().getValue(SPAN_PATH_KEY);\n if (spanPath) {\n span.setAttribute(SPAN_PATH, spanPath as string);\n }\n\n span.setAttribute(SPAN_INSTRUMENTATION_SOURCE, \"javascript\");\n\n // This sets the properties only if the context has them\n const associationProperties = context\n .active()\n .getValue(ASSOCIATION_PROPERTIES_KEY);\n if (associationProperties) {\n for (const [key, value] of Object.entries(associationProperties)) {\n if (Object.keys(ASSOCIATION_PROPERTIES_OVERRIDES).includes(key)) {\n span.setAttribute(ASSOCIATION_PROPERTIES_OVERRIDES[key], value);\n } else {\n span.setAttribute(`${ASSOCIATION_PROPERTIES}.${key}`, value);\n }\n }\n }\n };\n\n const provider = new NodeTracerProvider();\n provider.addSpanProcessor(_spanProcessor);\n provider.register();\n registerInstrumentations({\n instrumentations,\n tracerProvider: provider,\n });\n};\n\nexport const shouldSendTraces = () => {\n if (!_configuration) {\n return false;\n }\n\n if (\n _configuration.traceContent === false ||\n (process.env.TRACELOOP_TRACE_CONTENT || \"true\").toLowerCase() === \"false\"\n ) {\n return false;\n }\n\n return true;\n};\n\nexport const forceFlush = async () => {\n await _spanProcessor?.forceFlush();\n};\n","import { trace, createContextKey } from \"@opentelemetry/api\";\nimport { Context } from \"@opentelemetry/api/build/src/context/types\";\n\nconst TRACER_NAME = \"lmnr.tracer\";\nexport const SPAN_PATH_KEY = createContextKey(\"span_path\");\nexport const ASSOCIATION_PROPERTIES_KEY = createContextKey(\n \"association_properties\",\n);\n\nexport const getTracer = () => {\n return trace.getTracer(TRACER_NAME);\n};\n\nexport const getSpanPath = (entityContext: Context): string | undefined => {\n const path = entityContext.getValue(SPAN_PATH_KEY);\n\n return path ? `${path}` : undefined;\n};\n","import { SpanAttributes } from '@traceloop/ai-semantic-conventions';\n\nexport const SPAN_INPUT = \"lmnr.span.input\";\nexport const SPAN_OUTPUT = \"lmnr.span.output\";\nexport const SPAN_TYPE = \"lmnr.span.type\";\nexport const SPAN_PATH = \"lmnr.span.path\";\nexport const SPAN_INSTRUMENTATION_SOURCE = \"lmnr.span.instrumentation_source\";\nexport const OVERRIDE_PARENT_SPAN = \"lmnr.internal.override_parent_span\";\n\nexport const ASSOCIATION_PROPERTIES = \"lmnr.association.properties\";\nexport const SESSION_ID = \"lmnr.association.properties.session_id\";\nexport const USER_ID = \"lmnr.association.properties.user_id\";\nexport const TRACE_TYPE = \"lmnr.association.properties.trace_type\";\n\nexport const ASSOCIATION_PROPERTIES_OVERRIDES: Record<string, string> = {\n \"span_type\": SPAN_TYPE,\n};\n\nexport const LaminarAttributes = {\n // == This is the minimum set of attributes for a proper LLM span ==\n //\n // not SpanAttributes.LLM_USAGE_PROMPT_TOKENS\n INPUT_TOKEN_COUNT: \"gen_ai.usage.input_tokens\",\n // not SpanAttributes.LLM_USAGE_COMPLETION_TOKENS\n OUTPUT_TOKEN_COUNT: \"gen_ai.usage.output_tokens\",\n TOTAL_TOKEN_COUNT: SpanAttributes.LLM_USAGE_TOTAL_TOKENS,\n PROVIDER: SpanAttributes.LLM_SYSTEM,\n REQUEST_MODEL: SpanAttributes.LLM_REQUEST_MODEL,\n RESPONSE_MODEL: SpanAttributes.LLM_RESPONSE_MODEL,\n //\n // == End of minimum set ==\n // == Additional attributes ==\n //\n INPUT_COST: \"gen_ai.usage.input_cost\",\n OUTPUT_COST: \"gen_ai.usage.output_cost\",\n TOTAL_COST: \"gen_ai.usage.cost\",\n //\n // == End of additional attributes ==\n};\n","import { InitializeOptions } from \"../interfaces\";\nimport { startTracing } from \"../tracing\";\nimport { diag, DiagConsoleLogger, DiagLogLevel } from \"@opentelemetry/api\";\nimport { InitializationError } from \"../errors\";\n\nexport let _configuration: InitializeOptions | undefined;\n\n/**\n * Initializes the SDK.\n * Must be called once before any other SDK methods.\n *\n * @param options - The options to initialize the SDK. See the {@link InitializeOptions} for details.\n * @throws {InitializationError} if the configuration is invalid or if failed to fetch feature data.\n */\nexport const initialize = (options: InitializeOptions) => {\n if (_configuration) {\n return;\n }\n\n if (!options.baseUrl) {\n options.baseUrl =\n process.env.LMNR_BASE_URL || \"https://api.lmnr.ai:8443\";\n }\n if (!options.apiKey) {\n options.apiKey = process.env.LMNR_PROJECT_API_KEY;\n }\n if (options.apiKey && typeof options.apiKey !== \"string\") {\n throw new InitializationError('\"apiKey\" must be a string');\n }\n\n if (!options.appName) {\n options.appName = process.env.npm_package_name;\n }\n\n _configuration = Object.freeze(options);\n\n if (options.logLevel) {\n diag.setLogger(\n new DiagConsoleLogger(),\n logLevelToOtelLogLevel(options.logLevel),\n );\n }\n\n if (!options.silenceInitializationMessage) {\n console.log(\n `Laminar exporting traces to ${\n _configuration.exporter ? \"a custom exporter\" : _configuration.baseUrl\n }`,\n );\n }\n\n startTracing(_configuration);\n};\n\nconst logLevelToOtelLogLevel = (\n logLevel: \"debug\" | \"info\" | \"warn\" | \"error\",\n) => {\n switch (logLevel) {\n case \"debug\":\n return DiagLogLevel.DEBUG;\n case \"info\":\n return DiagLogLevel.INFO;\n case \"warn\":\n return DiagLogLevel.WARN;\n case \"error\":\n return DiagLogLevel.ERROR;\n }\n};\n","import { Span, TraceFlags, context, trace } from \"@opentelemetry/api\";\nimport { suppressTracing } from \"@opentelemetry/core\";\nimport {\n ASSOCIATION_PROPERTIES_KEY,\n getSpanPath,\n getTracer,\n SPAN_PATH_KEY,\n} from \"./tracing\";\nimport { shouldSendTraces } from \".\";\nimport { OVERRIDE_PARENT_SPAN, SPAN_INPUT, SPAN_OUTPUT } from \"./attributes\";\nimport { isStringUUID, uuidToOtelTraceId } from \"../../utils\";\nimport { RandomIdGenerator } from \"@opentelemetry/sdk-trace-base\";\n\nexport type DecoratorConfig = {\n name: string;\n associationProperties?: { [name: string]: string };\n inputParameters?: unknown[];\n suppressTracing?: boolean;\n traceId?: string;\n};\n\nexport function withEntity<\n A extends unknown[],\n F extends (...args: A) => ReturnType<F>,\n>(\n {\n name,\n associationProperties,\n inputParameters,\n suppressTracing: shouldSuppressTracing,\n traceId,\n }: DecoratorConfig,\n fn: F,\n thisArg?: ThisParameterType<F>,\n ...args: A\n) {\n let entityContext = context.active();\n\n const currentAssociationProperties = entityContext.getValue(ASSOCIATION_PROPERTIES_KEY);\n\n if (associationProperties) {\n entityContext = entityContext.setValue(\n ASSOCIATION_PROPERTIES_KEY,\n { ...(currentAssociationProperties ?? {}), ...associationProperties },\n );\n }\n\n const currentSpanPath = getSpanPath(entityContext);\n const spanPath = currentSpanPath ? `${currentSpanPath}.${name}` : name;\n entityContext = entityContext.setValue(SPAN_PATH_KEY, spanPath);\n if (traceId) {\n if (isStringUUID(traceId)) {\n const spanContext = {\n traceId: uuidToOtelTraceId(traceId),\n spanId: new RandomIdGenerator().generateSpanId(),\n traceFlags: TraceFlags.SAMPLED,\n isRemote: false,\n };\n entityContext = trace.setSpanContext(entityContext, spanContext);\n } else {\n console.warn(`Invalid trace ID ${traceId}. Expected a UUID.`);\n }\n }\n\n if (shouldSuppressTracing) {\n entityContext = suppressTracing(entityContext);\n }\n\n return context.with(entityContext, () =>\n getTracer().startActiveSpan(\n name,\n {},\n entityContext,\n async (span: Span) => {\n if (traceId && isStringUUID(traceId)) {\n span.setAttribute(OVERRIDE_PARENT_SPAN, true);\n }\n\n if (shouldSendTraces()) {\n try {\n const input = inputParameters ?? args;\n if (\n input.length === 1 &&\n typeof input[0] === \"object\" &&\n !(input[0] instanceof Map)\n ) {\n span.setAttribute(\n SPAN_INPUT,\n serialize(input[0]),\n );\n } else {\n // pass an array of the arguments without names\n // Need to convert it to hashmap from argument name to value, if we figure out how to do it elegantly\n span.setAttribute(\n SPAN_INPUT,\n serialize(input.length > 0 ? input : {}),\n );\n }\n } catch (error) {\n console.warn(\"Failed to serialize input\", error);\n }\n }\n\n // Remove span type from association properties after the span is created\n const { \"span_type\": spanType, ...rest } = associationProperties ?? {};\n entityContext = entityContext.setValue(\n ASSOCIATION_PROPERTIES_KEY,\n { ...(currentAssociationProperties ?? {}), ...rest },\n );\n\n const res = fn.apply(thisArg, args);\n\n if (res instanceof Promise) {\n return res.then((resolvedRes) => {\n try {\n if (shouldSendTraces()) {\n span.setAttribute(\n SPAN_OUTPUT,\n serialize(resolvedRes),\n );\n }\n } catch (error) {\n console.warn(\"Failed to serialize async output\", error);\n } finally {\n span.end();\n }\n\n return resolvedRes;\n });\n }\n try {\n if (shouldSendTraces()) {\n span.setAttribute(\n SPAN_OUTPUT,\n serialize(res),\n );\n }\n } catch (error) {\n console.warn(\"Failed to serialize output\", error);\n } finally {\n span.end();\n }\n\n return res;\n },\n ),\n );\n}\n\nfunction cleanInput(input: unknown): unknown {\n if (input instanceof Map) {\n return Array.from(input.entries());\n } else if (Array.isArray(input)) {\n return input.map((value) => cleanInput(value));\n } else if (!input) {\n return input;\n } else if (typeof input === \"object\") {\n // serialize object one by one\n const output: any = {};\n Object.entries(input as any).forEach(([key, value]) => {\n output[key] = cleanInput(value);\n });\n return output;\n }\n\n return input;\n}\n\nfunction serialize(input: unknown): string {\n return JSON.stringify(cleanInput(input));\n}\n","import { v4 as uuidv4 } from 'uuid';\n\nexport type StringUUID = `${string}-${string}-${string}-${string}-${string}`;\n\nexport const isStringUUID = (id: string): id is StringUUID => {\n return /^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/.test(id);\n}\n\nexport const newUUID = (): StringUUID => {\n // crypto.randomUUID is available in most of the modern browsers and node,\n // but is not available in \"insecure\" contexts, e.g. not https, not localhost\n // so we fallback to uuidv4 in those cases, which is less secure, but works\n // just fine.\n if (typeof crypto !== 'undefined' && typeof crypto.randomUUID === 'function') {\n return crypto.randomUUID();\n } else {\n return uuidv4() as `${string}-${string}-${string}-${string}-${string}`;\n }\n}\n\nexport const otelSpanIdToUUID = (spanId: string): string => {\n let id = spanId.toLowerCase();\n if (id.startsWith('0x')) {\n id = id.slice(2);\n }\n if (id.length !== 16) {\n console.warn(`Span ID ${spanId} is not 16 hex chars long. This is not a valid OpenTelemetry span ID.`);\n }\n\n if (!/^[0-9a-f]+$/.test(id)) {\n console.error(`Span ID ${spanId} is not a valid hex string. Generating a random UUID instead.`);\n return newUUID();\n }\n\n return id.padStart(32, '0').replace(/^(.{8})(.{4})(.{4})(.{4})(.{12})$/, '$1-$2-$3-$4-$5');\n}\n\nexport const otelTraceIdToUUID = (traceId: string): string => {\n let id = traceId.toLowerCase();\n if (id.startsWith('0x')) {\n id = id.slice(2);\n }\n if (id.length !== 32) {\n console.warn(`Trace ID ${traceId} is not 32 hex chars long. This is not a valid OpenTelemetry trace ID.`);\n }\n if (!/^[0-9a-f]+$/.test(id)) {\n console.error(`Trace ID ${traceId} is not a valid hex string. Generating a random UUID instead.`);\n return newUUID();\n }\n\n return id.replace(/^(.{8})(.{4})(.{4})(.{4})(.{12})$/, '$1-$2-$3-$4-$5');\n}\n\nexport const uuidToOtelTraceId = (uuid: string): string => {\n return uuid.replace(/-/g, '');\n}\n","import { Laminar } from \"./laminar\";\nimport { EvaluationDatapoint } from \"./types\";\nimport cliProgress from \"cli-progress\";\nimport { EvaluationDataset } from \"./datasets\";\nimport { otelSpanIdToUUID, otelTraceIdToUUID } from \"./utils\";\nimport { observe } from \"./decorators\";\nimport { trace } from \"@opentelemetry/api\";\nimport { SPAN_TYPE } from \"./sdk/tracing/attributes\";\nimport { InitializeOptions } from \"./sdk/interfaces\";\n\nconst DEFAULT_BATCH_SIZE = 5;\n\ndeclare global {\n var _evaluation: Evaluation<any, any, any> | undefined;\n // If true, then we need to set the evaluation globally without running it\n var _set_global_evaluation: boolean;\n}\n\nconst getEvaluationUrl = (projectId: string, evaluationId: string) => {\n return `https://www.lmnr.ai/project/${projectId}/evaluations/${evaluationId}`;\n}\n\nconst getAverageScores =\n <D, T, O>(results: EvaluationDatapoint<D, T, O>[]): Record<string, number> => {\n const perScoreValues: Record<string, number[]> = {};\n for (const result of results) {\n for (const key in result.scores) {\n if (perScoreValues[key]) {\n perScoreValues[key].push(result.scores[key]);\n } else {\n perScoreValues[key] = [result.scores[key]];\n }\n }\n }\n\n const averageScores: Record<string, number> = {};\n for (const key in perScoreValues) {\n averageScores[key] = perScoreValues[key].reduce((a, b) => a + b, 0)\n / perScoreValues[key].length;\n }\n\n return averageScores;\n }\n\n/**\n * Configuration for the Evaluator\n */\ninterface EvaluatorConfig {\n /**\n * The number of data points to evaluate in one batch. This many\n * data points will be evaluated in parallel. Defaults to 5.\n */\n batchSize?: number;\n /**\n * The project API key to use for the evaluation. If not provided,\n * the API key from the environment variable `LMNR_PROJECT_API_KEY` will be used.\n */\n projectApiKey?: string;\n /**\n * The base URL of the Laminar API. If not provided, the default is \n * `https://api.lmnr.ai`. Useful with self-hosted Laminar instances.\n * Do NOT include the port in the URL, use `httpPort` and `grpcPort` instead.\n */\n baseUrl?: string;\n /**\n * The HTTP port of the Laminar API. If not provided, the default is 443.\n */\n httpPort?: number;\n /**\n * The gRPC port of the Laminar API. If not provided, the default is 8443.\n */\n grpcPort?: number;\n /**\n * Object with modules to instrument. If not provided, all\n * available modules are instrumented.\n * See {@link https://docs.lmnr.ai/tracing/automatic-instrumentation}\n */\n instrumentModules?: InitializeOptions['instrumentModules'];\n}\n\n/**\n * Datapoint is a single data point in the evaluation. `D` is the type of the input data,\n * `T` is the type of the target data.\n */\nexport type Datapoint<D, T> = {\n /**\n * input to the executor function. Must be json serializable. Required.\n */\n data: D;\n /**\n * input to the evaluator function (alongside the executor output).\n * Must be json serializable.\n */\n target?: T;\n}\n\ntype EvaluatorFunctionReturn = number | Record<string, number>;\n\n/**\n * EvaluatorFunction is a function that takes the output of the executor and the\n * target data, and returns a score. The score can be a single number or a record\n * of string keys and number values. The latter is useful for evaluating\n * multiple criteria in one go instead of running multiple evaluators.\n */\ntype EvaluatorFunction<O, T> = (output: O, target: T | undefined, ...args: any[]) =>\n EvaluatorFunctionReturn | Promise<EvaluatorFunctionReturn>;\n\n/**\n * HumanEvaluator is an object to register a human evaluator. For now, it only\n * holds the queue name.\n */\nexport class HumanEvaluator {\n private queueName: string;\n\n constructor(queueName: string) {\n this.queueName = queueName;\n }\n}\n\ninterface EvaluationConstructorProps<D, T, O> {\n /**\n * List of data points to evaluate. `data` is the input to the executor function,\n * `target` is the input to the evaluator function.\n */\n data: (Datapoint<D, T>[]) | EvaluationDataset<D, T>;\n /**\n * The executor function. Takes the data point + any additional arguments\n * and returns the output to evaluate.\n */\n executor: (data: D, ...args: any[]) => O | Promise<O>;\n /**\n * Evaluator functions and names. Each evaluator function takes the output of\n * the executor _and_ the target data, and returns a score. The score can be a\n * single number or a dict of string keys and number values. If the score is a\n * single number, it will be named after the evaluator function. Evaluator\n * function names must contain only letters, digits, hyphens, underscores,\n * or spaces.\n */\n evaluators: Record<string, EvaluatorFunction<O, T>>;\n /**\n * [Beta] Array of instances of {@link HumanEvaluator}.\n * For now, HumanEvaluator only holds the queue name.\n */\n humanEvaluators?: HumanEvaluator[];\n /**\n * Name of the evaluation. If not provided, a random name will be assigned.\n */\n name?: string;\n /**\n * Optional group id of the evaluation. Only evaluations within the same\n * group_id can be visually compared. Defaults to \"default\".\n */\n groupId?: string;\n /**\n * Optional override configurations for the evaluator.\n */\n config?: EvaluatorConfig;\n}\n\n/**\n * Reports the whole progress to the console.\n */\nclass EvaluationReporter {\n private cliProgress: cliProgress.SingleBar = new cliProgress.SingleBar(\n {},\n cliProgress.Presets.shades_classic\n );\n private progressCounter: number = 0;\n\n constructor() { }\n\n public start({ length }: { length: number }) {\n this.cliProgress.start(length, 0);\n }\n\n public update(batchLength: number) {\n this.progressCounter += batchLength;\n this.cliProgress.update(this.progressCounter);\n }\n\n // Call either error or stop, not both\n public stopWithError(error: Error) {\n this.cliProgress.stop();\n process.stdout.write(`\\nError: ${error.message}\\n`);\n }\n\n // Call either error or stop, not both\n public stop({\n averageScores,\n projectId,\n evaluationId\n }: { averageScores: Record<string, number>, projectId: string, evaluationId: string }) {\n this.cliProgress.stop();\n process.stdout.write(`\\nCheck results at ${getEvaluationUrl(projectId, evaluationId)}\\n`);\n process.stdout.write('\\nAverage scores:\\n');\n for (const key in averageScores) {\n process.stdout.write(`${key}: ${JSON.stringify(averageScores[key])}\\n`);\n }\n process.stdout.write('\\n');\n }\n}\n\nclass Evaluation<D, T, O> {\n private isFinished: boolean = false;\n private progressReporter: EvaluationReporter;\n private data: Datapoint<D, T>[] | EvaluationDataset<D, T>;\n private executor: (data: D, ...args: any[]) => O | Promise<O>;\n private evaluators: Record<string, EvaluatorFunction<O, T>>;\n private humanEvaluators?: HumanEvaluator[];\n private groupId?: string;\n private name?: string;\n private batchSize: number = DEFAULT_BATCH_SIZE;\n\n constructor({\n data, executor, evaluators, humanEvaluators, groupId, name, config\n }: EvaluationConstructorProps<D, T, O>) {\n if (Object.keys(evaluators).length === 0) {\n throw new Error('No evaluators provided');\n }\n\n const evaluatorNameRegex = /^[\\w\\s-]+$/;\n // Validate evaluator keys\n for (const key in evaluators) {\n if (!evaluatorNameRegex.test(key)) {\n throw new Error(\n `Invalid evaluator key: \"${key}\".` +\n \"Keys must only contain letters, digits, hyphens, underscores, or spaces.\"\n );\n }\n }\n\n this.progressReporter = new EvaluationReporter();\n this.data = data;\n this.executor = executor;\n this.evaluators = evaluators;\n this.humanEvaluators = humanEvaluators;\n this.groupId = groupId;\n this.name = name;\n if (config) {\n this.batchSize = config.batchSize ?? DEFAULT_BATCH_SIZE;\n }\n Laminar.initialize({\n projectApiKey: config?.projectApiKey,\n baseUrl: config?.baseUrl,\n httpPort: config?.httpPort,\n grpcPort: config?.grpcPort,\n instrumentModules: config?.instrumentModules\n });\n }\n\n public async run(): Promise<void> {\n if (this.isFinished) {\n throw new Error('Evaluation is already finished');\n }\n\n this.progressReporter.start({ length: await this.getLength() });\n let resultDatapoints: EvaluationDatapoint<D, T, O>[];\n try {\n resultDatapoints = await this.evaluateInBatches();\n } catch (e) {\n this.progressReporter.stopWithError(e as Error);\n this.isFinished = true;\n return;\n }\n\n const evaluation = await Laminar.createEvaluation({\n groupId: this.groupId,\n name: this.name,\n data: resultDatapoints\n });\n const averageScores = getAverageScores(resultDatapoints);\n this.progressReporter.stop({\n averageScores,\n projectId: evaluation.projectId,\n evaluationId: evaluation.id\n });\n this.isFinished = true;\n\n await Laminar.shutdown();\n }\n\n public async evaluateInBatches(): Promise<EvaluationDatapoint<D, T, O>[]> {\n const resultDatapoints: EvaluationDatapoint<D, T, O>[] = [];\n for (let i = 0; i < await this.getLength(); i += this.batchSize) {\n const batch = await this.data.slice(i, i + this.batchSize);\n const batchDatapoints = await this.evaluateBatch(batch);\n resultDatapoints.push(...batchDatapoints);\n this.progressReporter.update(batch.length);\n }\n return resultDatapoints;\n }\n\n private async evaluateBatch(batch: Datapoint<D, T>[]): Promise<EvaluationDatapoint<D, T, O>[]> {\n const batchPromises = batch.map(async (datapoint) => {\n let ret: EvaluationDatapoint<D, T, O> | undefined;\n\n // NOTE: If you decide to move this observe to another place, note that\n // traceId is assigned inside it for EvaluationDatapoint\n await observe({ name: \"evaluation\", traceType: \"EVALUATION\" }, async () => {\n trace.getActiveSpan()!.setAttribute(SPAN_TYPE, \"EVALUATION\");\n\n const { output, executorSpanId } = await observe(\n { name: \"executor\" },\n async (data: D) => {\n const executorSpanId = trace.getActiveSpan()!.spanContext().spanId;\n trace.getActiveSpan()!.setAttribute(SPAN_TYPE, \"EXECUTOR\");\n return {\n output: await this.executor(data),\n executorSpanId: otelSpanIdToUUID(executorSpanId)\n };\n },\n datapoint.data\n );\n const target = datapoint.target;\n\n let scores: Record<string, number> = {};\n for (const [evaluatorName, evaluator] of Object.entries(this.evaluators)) {\n const value = await observe(\n { name: evaluatorName },\n async (output: O, target?: T) => {\n trace.getActiveSpan()!.setAttribute(SPAN_TYPE, \"EVALUATOR\");\n return await evaluator(output, target);\n },\n output,\n target\n );\n\n if (typeof value === 'number') {\n if (isNaN(value)) {\n throw new Error(`Evaluator ${evaluatorName} returned NaN`);\n }\n scores[evaluatorName] = value;\n } else {\n scores = { ...scores, ...value };\n }\n }\n\n ret = {\n executorOutput: output,\n data: datapoint.data,\n target,\n scores,\n traceId: otelTraceIdToUUID(trace.getActiveSpan()!.spanContext().traceId),\n // For now, all human evaluators are added to every datapoint\n // In the future, we will allow to specify which evaluators are\n // added to a particular datapoint, e.g. random sampling.\n humanEvaluators: this.humanEvaluators,\n executorSpanId\n } as EvaluationDatapoint<D, T, O>;\n });\n\n return ret!;\n });\n\n const results = await Promise.all(batchPromises);\n\n return results;\n }\n\n private async getLength(): Promise<number> {\n return this.data instanceof EvaluationDataset ? await this.data.size() : this.data.length;\n }\n}\n\n/**\n * If added to the file which is called through lmnr eval command, then simply\n * registers the evaluation. Otherwise, returns a promise which resolves when\n * the evaluation is finished. If the evaluation has no async logic, then it\n * will be executed synchronously.\n *\n * @param props.data List of data points to evaluate. `data` is the input to the\n * executor function, `target` is the input to the evaluator function.\n * @param props.executor The executor function. Takes the data point + any\n * additional arguments and returns the output to evaluate.\n * @param props.evaluators Map from evaluator name to evaluator function. Each\n * evaluator function takes the output of the executor and the target data, and\n * returns.\n * @param props.humanEvaluators [Beta] Array of instances of {@link HumanEvaluator}.\n * For now, HumanEvaluator only holds the queue name.\n * @param props.groupId Group name which is same as the feature you are evaluating\n * in your project or application. Defaults to \"default\".\n * @param props.name Optional name of the evaluation. Used to easily identify\n * the evaluation in the group.\n * @param props.config Optional override configurations for the evaluator.\n */\nexport async function evaluate<D, T, O>({\n data, executor, evaluators, humanEvaluators, groupId, name, config\n}: EvaluationConstructorProps<D, T, O>): Promise<void> {\n const evaluation = new Evaluation({\n data,\n executor,\n evaluators,\n humanEvaluators,\n name,\n groupId,\n config\n });\n if (globalThis._set_global_evaluation) {\n globalThis._evaluation = evaluation;\n } else {\n await evaluation.run();\n }\n}\n","import { Datapoint } from './evaluations';\nimport { Laminar as L } from './laminar';\n\nconst DEFAULT_FETCH_SIZE = 25;\n\nexport abstract class EvaluationDataset<D, T> {\n public async slice(start: number, end: number): Promise<Datapoint<D, T>[]> {\n const result = [];\n for (let i = Math.max(start, 0); i < Math.min(end, await this.size()); i++) {\n result.push(await this.get(i));\n }\n return result;\n }\n public abstract size(): Promise<number> | number;\n public abstract get(index: number): Promise<Datapoint<D, T>> | Datapoint<D, T>;\n}\n\nexport class LaminarDataset<D, T> extends EvaluationDataset<D, T> {\n private fetchedItems: Datapoint<D, T>[] = [];\n private len: number | null = null;\n private offset: number = 0;\n private fetchSize: number;\n private name: string;\n\n constructor(name: string, fetchSize?: number) {\n super();\n this.name = name;\n this.fetchSize = fetchSize || DEFAULT_FETCH_SIZE;\n }\n\n private async fetchBatch() {\n // Commented out until we allow users to set log level\n // console.debug(`Dataset ${this.name}. Fetching batch from ${this.offset} to ${this.offset + this.fetchSize}`);\n const resp = await L.getDatapoints<D, T>({\n datasetName: this.name,\n offset: this.offset,\n limit: this.fetchSize,\n });\n this.fetchedItems = this.fetchedItems.concat(resp.items);\n this.offset = this.fetchedItems.length;\n if (this.len === null) {\n this.len = resp.totalCount;\n }\n }\n\n public async size(): Promise<number> {\n if (this.len === null) {\n await this.fetchBatch();\n }\n return this.len!;\n }\n public async get(index: number): Promise<Datapoint<D, T>> {\n if (index >= this.fetchedItems.length) {\n await this.fetchBatch();\n }\n return this.fetchedItems[index];\n }\n}\n","import { Span, TraceFlags, context, trace } from \"@opentelemetry/api\";\nimport { withEntity } from './sdk/node-server-sdk'\nimport { Laminar } from './laminar';\nimport { TraceType } from './types';\nimport { ASSOCIATION_PROPERTIES_KEY } from \"./sdk/tracing/tracing\";\n\ninterface ObserveOptions {\n name?: string;\n sessionId?: string;\n userId?: string;\n traceType?: TraceType;\n spanType?: 'DEFAULT' | 'LLM';\n traceId?: string;\n}\n\n/**\n * The main decorator entrypoint for Laminar. This is used to wrap\n * functions and methods to create spans.\n *\n * @param name - Name of the span. Function name is used if not specified.\n * @param userId - User ID to associate with the span and the following context.\n * @param sessionId - Session ID to associate with the span and the following context.\n * @param traceType – Type of the trace. Unless it is within evaluation, it should be 'DEFAULT'.\n * @param spanType - Type of the span. 'DEFAULT' is used if not specified. If the type is 'LLM',\n * you must manually specify some attributes. See {@link Laminar.setSpanAttributes} for more\n * information.\n * @returns Returns the result of the wrapped function.\n * @throws Exception - Re-throws the exception if the wrapped function throws an exception.\n * \n * @example\n * ```typescript\n * import { observe } from '@lmnr-ai/lmnr';\n * \n * await observe({ name: 'my_function' }, () => {\n * // Your code here\n * });\n */\nexport async function observe<A extends unknown[], F extends (...args: A) => ReturnType<F>>(\n {\n name,\n sessionId,\n userId,\n traceType,\n spanType,\n traceId,\n }: ObserveOptions, fn: F, ...args: A): Promise<ReturnType<F>> {\n if (fn === undefined || typeof fn !== \"function\") {\n throw new Error(\"Invalid `observe` usage. Second argument `fn` must be a function.\");\n }\n\n let associationProperties = {};\n if (sessionId) {\n associationProperties = { ...associationProperties, \"session_id\": sessionId };\n }\n if (userId) {\n associationProperties = { ...associationProperties, \"user_id\": userId };\n }\n if (traceType) {\n associationProperties = { ...associationProperties, \"trace_type\": traceType };\n }\n if (spanType) {\n associationProperties = { ...associationProperties, \"span_type\": spanType };\n }\n\n return await withEntity<A, F>({\n name: name ?? fn.name,\n associationProperties,\n traceId\n }, fn, undefined, ...args);\n}\n\n/**\n * Sets the labels for any spans inside the function. This is useful for adding\n * labels to the spans created in the auto-instrumentations. Returns the result\n * of the wrapped function, so you can use it in an `await` statement if needed.\n * \n * Requirements:\n * - Labels must be created in your project in advance.\n * - Keys must be strings from your label names.\n * - Values must be strings matching the label's allowed values.\n * \n * @param labels - The labels to set.\n * @returns The result of the wrapped function.\n * \n * @example\n * ```typescript\n * import { withLabels } from '@lmnr-ai/lmnr';\n * \n * const result = await withLabels({ endpoint: \"ft-openai-<id>\" }, () => {\n * openai.chat.completions.create({});\n * });\n * ```\n */\nexport function withLabels<A extends unknown[], F extends (...args: A) => ReturnType<F>>(\n labels: Record<string, string>,\n fn: F,\n ...args: A\n): ReturnType<F> {\n let entityContext = context.active();\n const currentAssociationProperties = entityContext.getValue(ASSOCIATION_PROPERTIES_KEY) ?? {};\n const labelProperties = Object.entries(labels).reduce((acc, [key, value]) => {\n acc[`label.${key}`] = value;\n return acc;\n }, {} as Record<string, string>);\n\n entityContext = entityContext.setValue(\n ASSOCIATION_PROPERTIES_KEY,\n { ...currentAssociationProperties, ...labelProperties },\n );\n\n const result = context.with(entityContext, () => {\n return fn.apply(undefined, args);\n });\n\n const newAssociationProperties = (entityContext.getValue(ASSOCIATION_PROPERTIES_KEY) ?? {}) as Record<string, any>;\n for (const [key, value] of Object.entries(labelProperties)) {\n delete newAssociationProperties[`label.${key}`];\n }\n\n entityContext = entityContext.setValue(\n ASSOCIATION_PROPERTIES_KEY,\n newAssociationProperties,\n );\n\n return result;\n}\n"],"mappings":"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","names":["import_api","import_api","import_api","import_api","import_core","uuidv4","import_sdk_trace_base","contextApi","context","import_api","import_api","cliProgress","executorSpanId","output","target","import_api"]}
|
package/dist/index.mjs
CHANGED
|
@@ -838,10 +838,11 @@ var Laminar = class {
|
|
|
838
838
|
name,
|
|
839
839
|
input,
|
|
840
840
|
spanType,
|
|
841
|
-
context:
|
|
842
|
-
traceId
|
|
841
|
+
context: context4,
|
|
842
|
+
traceId,
|
|
843
|
+
labels
|
|
843
844
|
}) {
|
|
844
|
-
let entityContext =
|
|
845
|
+
let entityContext = context4 != null ? context4 : contextApi.active();
|
|
845
846
|
const currentSpanPath = getSpanPath(entityContext);
|
|
846
847
|
const spanPath = currentSpanPath ? `${currentSpanPath}.${name}` : name;
|
|
847
848
|
entityContext = entityContext.setValue(SPAN_PATH_KEY, spanPath);
|
|
@@ -858,9 +859,14 @@ var Laminar = class {
|
|
|
858
859
|
console.warn(`Invalid trace ID ${traceId}. Expected a UUID.`);
|
|
859
860
|
}
|
|
860
861
|
}
|
|
862
|
+
const labelProperties = labels ? Object.entries(labels).reduce((acc, [key, value]) => {
|
|
863
|
+
acc[`${ASSOCIATION_PROPERTIES}.label.${key}`] = value;
|
|
864
|
+
return acc;
|
|
865
|
+
}, {}) : {};
|
|
861
866
|
const attributes = {
|
|
862
867
|
[SPAN_TYPE]: spanType != null ? spanType : "DEFAULT",
|
|
863
|
-
[
|
|
868
|
+
[SPAN_PATH]: spanPath,
|
|
869
|
+
...labelProperties
|
|
864
870
|
};
|
|
865
871
|
const span = getTracer().startSpan(name, { attributes }, entityContext);
|
|
866
872
|
if (traceId) {
|
|
@@ -1003,6 +1009,7 @@ var LaminarDataset = class extends EvaluationDataset {
|
|
|
1003
1009
|
};
|
|
1004
1010
|
|
|
1005
1011
|
// src/decorators.ts
|
|
1012
|
+
import { context as context3 } from "@opentelemetry/api";
|
|
1006
1013
|
async function observe({
|
|
1007
1014
|
name,
|
|
1008
1015
|
sessionId,
|
|
@@ -1011,6 +1018,9 @@ async function observe({
|
|
|
1011
1018
|
spanType,
|
|
1012
1019
|
traceId
|
|
1013
1020
|
}, fn, ...args) {
|
|
1021
|
+
if (fn === void 0 || typeof fn !== "function") {
|
|
1022
|
+
throw new Error("Invalid `observe` usage. Second argument `fn` must be a function.");
|
|
1023
|
+
}
|
|
1014
1024
|
let associationProperties = {};
|
|
1015
1025
|
if (sessionId) {
|
|
1016
1026
|
associationProperties = { ...associationProperties, "session_id": sessionId };
|
|
@@ -1030,9 +1040,34 @@ async function observe({
|
|
|
1030
1040
|
traceId
|
|
1031
1041
|
}, fn, void 0, ...args);
|
|
1032
1042
|
}
|
|
1043
|
+
function withLabels(labels, fn, ...args) {
|
|
1044
|
+
var _a, _b;
|
|
1045
|
+
let entityContext = context3.active();
|
|
1046
|
+
const currentAssociationProperties = (_a = entityContext.getValue(ASSOCIATION_PROPERTIES_KEY)) != null ? _a : {};
|
|
1047
|
+
const labelProperties = Object.entries(labels).reduce((acc, [key, value]) => {
|
|
1048
|
+
acc[`label.${key}`] = value;
|
|
1049
|
+
return acc;
|
|
1050
|
+
}, {});
|
|
1051
|
+
entityContext = entityContext.setValue(
|
|
1052
|
+
ASSOCIATION_PROPERTIES_KEY,
|
|
1053
|
+
{ ...currentAssociationProperties, ...labelProperties }
|
|
1054
|
+
);
|
|
1055
|
+
const result = context3.with(entityContext, () => {
|
|
1056
|
+
return fn.apply(void 0, args);
|
|
1057
|
+
});
|
|
1058
|
+
const newAssociationProperties = (_b = entityContext.getValue(ASSOCIATION_PROPERTIES_KEY)) != null ? _b : {};
|
|
1059
|
+
for (const [key, value] of Object.entries(labelProperties)) {
|
|
1060
|
+
delete newAssociationProperties[`label.${key}`];
|
|
1061
|
+
}
|
|
1062
|
+
entityContext = entityContext.setValue(
|
|
1063
|
+
ASSOCIATION_PROPERTIES_KEY,
|
|
1064
|
+
newAssociationProperties
|
|
1065
|
+
);
|
|
1066
|
+
return result;
|
|
1067
|
+
}
|
|
1033
1068
|
|
|
1034
1069
|
// src/evaluations.ts
|
|
1035
|
-
import { trace as
|
|
1070
|
+
import { trace as trace5 } from "@opentelemetry/api";
|
|
1036
1071
|
var DEFAULT_BATCH_SIZE = 5;
|
|
1037
1072
|
var getEvaluationUrl = (projectId, evaluationId) => {
|
|
1038
1073
|
return `https://www.lmnr.ai/project/${projectId}/evaluations/${evaluationId}`;
|
|
@@ -1182,12 +1217,12 @@ var Evaluation = class {
|
|
|
1182
1217
|
const batchPromises = batch.map(async (datapoint) => {
|
|
1183
1218
|
let ret;
|
|
1184
1219
|
await observe({ name: "evaluation", traceType: "EVALUATION" }, async () => {
|
|
1185
|
-
|
|
1220
|
+
trace5.getActiveSpan().setAttribute(SPAN_TYPE, "EVALUATION");
|
|
1186
1221
|
const { output, executorSpanId } = await observe(
|
|
1187
1222
|
{ name: "executor" },
|
|
1188
1223
|
async (data) => {
|
|
1189
|
-
const executorSpanId2 =
|
|
1190
|
-
|
|
1224
|
+
const executorSpanId2 = trace5.getActiveSpan().spanContext().spanId;
|
|
1225
|
+
trace5.getActiveSpan().setAttribute(SPAN_TYPE, "EXECUTOR");
|
|
1191
1226
|
return {
|
|
1192
1227
|
output: await this.executor(data),
|
|
1193
1228
|
executorSpanId: otelSpanIdToUUID(executorSpanId2)
|
|
@@ -1201,7 +1236,7 @@ var Evaluation = class {
|
|
|
1201
1236
|
const value = await observe(
|
|
1202
1237
|
{ name: evaluatorName },
|
|
1203
1238
|
async (output2, target2) => {
|
|
1204
|
-
|
|
1239
|
+
trace5.getActiveSpan().setAttribute(SPAN_TYPE, "EVALUATOR");
|
|
1205
1240
|
return await evaluator(output2, target2);
|
|
1206
1241
|
},
|
|
1207
1242
|
output,
|
|
@@ -1221,7 +1256,7 @@ var Evaluation = class {
|
|
|
1221
1256
|
data: datapoint.data,
|
|
1222
1257
|
target,
|
|
1223
1258
|
scores,
|
|
1224
|
-
traceId: otelTraceIdToUUID(
|
|
1259
|
+
traceId: otelTraceIdToUUID(trace5.getActiveSpan().spanContext().traceId),
|
|
1225
1260
|
// For now, all human evaluators are added to every datapoint
|
|
1226
1261
|
// In the future, we will allow to specify which evaluators are
|
|
1227
1262
|
// added to a particular datapoint, e.g. random sampling.
|
|
@@ -1264,15 +1299,16 @@ async function evaluate({
|
|
|
1264
1299
|
}
|
|
1265
1300
|
|
|
1266
1301
|
// src/index.ts
|
|
1267
|
-
import { Span as
|
|
1302
|
+
import { Span as Span5 } from "@opentelemetry/api";
|
|
1268
1303
|
export {
|
|
1269
1304
|
EvaluationDataset as Dataset,
|
|
1270
1305
|
HumanEvaluator,
|
|
1271
1306
|
Laminar,
|
|
1272
1307
|
LaminarAttributes,
|
|
1273
1308
|
LaminarDataset,
|
|
1274
|
-
|
|
1309
|
+
Span5 as Span,
|
|
1275
1310
|
evaluate,
|
|
1276
|
-
observe
|
|
1311
|
+
observe,
|
|
1312
|
+
withLabels
|
|
1277
1313
|
};
|
|
1278
1314
|
//# sourceMappingURL=index.mjs.map
|