@lmnr-ai/lmnr 0.4.21 → 0.4.22

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/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, 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":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;;ACOA,IAAAA,cAUO;;;ACdA,IAAM,WAAW;AAAA,EACtB,SAAS;AAAA,EACT,OAAO;AAAA,EACP,UAAU;AACZ;AAOO,IAAM,iBAAN,cAA6B,MAAM;AAAA,EAUxC,YAAY,SAAiB,WAAqB,SAAS,OAAO;AAChE,UAAM,OAAO;AACb,SAAK,WAAW;AAAA,EAClB;AACF;AAWO,IAAM,sBAAN,cAAkC,eAAe;AAAA,EACtD,YAAY,SAAkB,OAAe;AAC3C,UAAM,4BAAW,sCAAsC,SAAS,QAAQ;AACxE,SAAK,kBAAkB;AAAA,EACzB;AACF;;;AC3CA,kBAA6B;AAC7B,IAAAC,cAAoC;AACpC,uCAAkC;;;ACHlC,iBAAwC;AAGxC,IAAM,cAAc;AACb,IAAM,oBAAgB,6BAAiB,WAAW;AAClD,IAAM,iCAA6B;AAAA,EACxC;AACF;AAEO,IAAM,YAAY,MAAM;AAC7B,SAAO,iBAAM,UAAU,WAAW;AACpC;AAEO,IAAM,cAAc,CAAC,kBAA+C;AACzE,QAAM,OAAO,cAAc,SAAS,aAAa;AAEjD,SAAO,OAAO,GAAG,IAAI,KAAK;AAC5B;;;ADNA,4BAA4E;AAC5E,6BAAyC;AACzC,uCAAyC;AACzC,oCAAsC;AACtC,mCAA2C;AAC3C,wCAA0C;AAC1C,sCAGO;AACP,qCAAuC;AACvC,oCAAsC;AACtC,sCAAwC;AACxC,uCAAyC;AACzC,sCAAwC;AACxC,oCAAsC;;;AE1BtC,qCAA+B;AAExB,IAAM,aAAa;AACnB,IAAM,cAAc;AACpB,IAAM,YAAY;AAClB,IAAM,YAAY;AAClB,IAAM,8BAA8B;AACpC,IAAM,uBAAuB;AAE7B,IAAM,yBAAyB;AAC/B,IAAM,aAAa;AACnB,IAAM,UAAU;AAGhB,IAAM,mCAA2D;AAAA,EACtE,aAAa;AACf;AAEO,IAAM,oBAAoB;AAAA;AAAA;AAAA;AAAA,EAI/B,mBAAmB;AAAA;AAAA,EAEnB,oBAAoB;AAAA,EACpB,mBAAmB,8CAAe;AAAA,EAClC,UAAU,8CAAe;AAAA,EACzB,eAAe,8CAAe;AAAA,EAC9B,gBAAgB,8CAAe;AAAA;AAAA;AAAA;AAAA;AAAA,EAK/B,YAAY;AAAA,EACZ,aAAa;AAAA,EACb,YAAY;AAAA;AAAA;AAGd;;;AFTA,IAAI;AACJ,IAAI;AACJ,IAAI;AACJ,IAAI;AACJ,IAAI;AACJ,IAAI;AACJ,IAAI;AACJ,IAAI;AACJ,IAAI;AACJ,IAAI;AACJ,IAAI;AACJ,IAAI;AACJ,IAAI;AAGJ,IAAM,mBAAsC,CAAC;AAE7C,IAAM,uBAAuB,MAAM;AACjC,QAAM,eAAe;AAErB,0BAAwB,IAAI,oDAAsB;AAAA,IAChD;AAAA,EACF,CAAC;AACD,mBAAiB,KAAK,qBAAqB;AAE3C,6BAA2B,IAAI,0DAAyB;AACxD,mBAAiB,KAAK,wBAAwB;AAE9C,+BAA6B,IAAI,wDAA2B;AAC5D,mBAAiB,KAAK,0BAA0B;AAEhD,0BAAwB,IAAI,oDAAsB;AAClD,mBAAiB,KAAK,qBAAqB;AAE3C,4BAA0B,IAAI,wDAAwB;AACtD,mBAAiB,KAAK,uBAAuB;AAE7C,8BAA4B,IAAI,0DAA0B;AAC1D,mBAAiB,KAAK,yBAAyB;AAE/C,2BAAyB,IAAI,sDAAuB;AACpD,mBAAiB,KAAK,sBAAsB;AAE5C,4BAA0B,IAAI,wDAAwB;AACtD,mBAAiB,KAAK,uBAAuB;AAE7C,6BAA2B,IAAI,0DAAyB;AACxD,mBAAiB,KAAK,wBAAwB;AAE9C,8BAA4B,IAAI,4DAA0B;AAC1D,mBAAiB,KAAK,yBAAyB;AAE/C,4BAA0B,IAAI,wDAAwB;AACtD,mBAAiB,KAAK,uBAAuB;AAE7C,0BAAwB,IAAI,oDAAsB;AAClD,mBAAiB,KAAK,qBAAqB;AAC7C;AAEA,IAAM,+BAA+B,CACnC,sBACG;AACH,QAAM,eAAe;AAErB,mBAAiB,SAAS;AAE1B,MAAI,uDAAmB,QAAQ;AAC7B,4BAAwB,IAAI,oDAAsB;AAAA,MAChD;AAAA,IACF,CAAC;AACD,qBAAiB,KAAK,qBAAqB;AAC3C,0BAAsB,mBAAmB,kBAAkB,MAAM;AAAA,EACnE;AAEA,MAAI,uDAAmB,WAAW;AAChC,+BAA2B,IAAI,0DAAyB;AACxD,qBAAiB,KAAK,wBAAwB;AAC9C,6BAAyB,mBAAmB,kBAAkB,SAAS;AAAA,EACzE;AAEA,MAAI,uDAAmB,aAAa;AAClC,UAAM,kBAAkB,IAAI,wDAA2B;AACvD,qBAAiB,KAAK,eAAkC;AACxD,iCAA6B;AAC7B,oBAAgB,mBAAmB,kBAAkB,WAAW;AAAA,EAClE;AAEA,MAAI,uDAAmB,QAAQ;AAC7B,4BAAwB,IAAI,oDAAsB;AAClD,qBAAiB,KAAK,qBAAqB;AAC3C,0BAAsB,mBAAmB,kBAAkB,MAAM;AAAA,EACnE;AAEA,MAAI,uDAAmB,iBAAiB;AACtC,8BAA0B,IAAI,wDAAwB;AACtD,qBAAiB,KAAK,uBAAuB;AAC7C,4BAAwB;AAAA,MACtB,kBAAkB;AAAA,IACpB;AAAA,EACF;AAEA,MAAI,uDAAmB,mBAAmB;AACxC,gCAA4B,IAAI,0DAA0B;AAC1D,qBAAiB,KAAK,yBAAyB;AAC/C,8BAA0B;AAAA,MACxB,kBAAkB;AAAA,IACpB;AAAA,EACF;AAEA,MAAI,uDAAmB,SAAS;AAC9B,6BAAyB,IAAI,sDAAuB;AACpD,qBAAiB,KAAK,sBAAsB;AAC5C,2BAAuB,mBAAmB,kBAAkB,OAAO;AAAA,EACrE;AAEA,MAAI,uDAAmB,UAAU;AAC/B,UAAM,kBAAkB,IAAI,wDAAwB;AACpD,qBAAiB,KAAK,eAAkC;AACxD,oBAAgB,mBAAmB,kBAAkB,QAAQ;AAAA,EAC/D;AAEA,MAAI,uDAAmB,WAAW;AAChC,+BAA2B,IAAI,0DAAyB;AACxD,qBAAiB,KAAK,wBAAwB;AAC9C,6BAAyB,mBAAmB,kBAAkB,SAAS;AAAA,EACzE;AAEA,MAAI,uDAAmB,YAAY;AACjC,gCAA4B,IAAI,4DAA0B;AAC1D,qBAAiB,KAAK,yBAAyB;AAC/C,8BAA0B,mBAAmB,kBAAkB,UAAU;AAAA,EAC3E;AAEA,MAAI,uDAAmB,UAAU;AAC/B,8BAA0B,IAAI,wDAAwB;AACtD,qBAAiB,KAAK,uBAAuB;AAC7C,4BAAwB,mBAAmB,kBAAkB,QAAQ;AAAA,EACvE;AAEA,MAAI,uDAAmB,QAAQ;AAC7B,4BAAwB,IAAI,oDAAsB;AAClD,qBAAiB,KAAK,qBAAqB;AAC3C,0BAAsB,mBAAmB,kBAAkB,MAAM;AAAA,EACnE;AACF;AAQO,IAAM,eAAe,CAAC,YAA+B;AArL5D;AAsLE,MAAI,QAAQ,sBAAsB,QAAW;AAG3C,iCAA6B,QAAQ,iBAAiB;AAAA,EACxD,OAAO;AACL,yBAAqB;AAAA,EACvB;AAEA,MAAI,CAAC,iBAAiB,GAAG;AACvB,mEAAuB,UAAU;AAAA,MAC/B,cAAc;AAAA,IAChB;AACA,6EAA4B,UAAU;AAAA,MACpC,cAAc;AAAA,IAChB;AACA,2EAA2B,UAAU;AAAA,MACnC,cAAc;AAAA,IAChB;AACA,uEAAyB,UAAU;AAAA,MACjC,cAAc;AAAA,IAChB;AACA,2EAA2B,UAAU;AAAA,MACnC,cAAc;AAAA,IAChB;AACA,qEAAwB,UAAU;AAAA,MAChC,cAAc;AAAA,IAChB;AACA,mEAAuB,UAAU;AAAA,MAC/B,cAAc;AAAA,IAChB;AACA,uEAAyB,UAAU;AAAA,MACjC,cAAc;AAAA,IAChB;AAAA,EACF;AAEA,QAAM,UAAU,QAAQ,IAAI,oBACxB,yBAAa,wBAAwB,QAAQ,IAAI,iBAAiB,IAClE,EAAE,eAAe,UAAU,QAAQ,MAAM,GAAG;AAEhD,QAAM,iBACJ,aAAQ,aAAR,YACA,IAAI,mDAAkB;AAAA,IACpB,KAAK,GAAG,QAAQ,OAAO;AAAA,IACvB;AAAA,EACF,CAAC;AACH,mBAAiB,QAAQ,eACrB,IAAI,0CAAoB,aAAa,IACrC,IAAI,yCAAmB,aAAa;AAExC,iBAAe,UAAU,CAAC,SAAe;AACvC,UAAM,WAAW,oBAAQ,OAAO,EAAE,SAAS,aAAa;AACxD,QAAI,UAAU;AACZ,WAAK,aAAa,WAAW,QAAkB;AAAA,IACjD;AAEA,SAAK,aAAa,6BAA6B,YAAY;AAG3D,UAAM,wBAAwB,oBAC3B,OAAO,EACP,SAAS,0BAA0B;AACtC,QAAI,uBAAuB;AACzB,iBAAW,CAAC,KAAK,KAAK,KAAK,OAAO,QAAQ,qBAAqB,GAAG;AAChE,YAAI,OAAO,KAAK,gCAAgC,EAAE,SAAS,GAAG,GAAG;AAC/D,eAAK,aAAa,iCAAiC,GAAG,GAAG,KAAK;AAAA,QAChE,OAAO;AACL,eAAK,aAAa,GAAG,sBAAsB,IAAI,GAAG,IAAI,KAAK;AAAA,QAC7D;AAAA,MACF;AAAA,IACF;AAAA,EACF;AAEA,QAAM,WAAW,IAAI,yCAAmB;AACxC,WAAS,iBAAiB,cAAc;AACxC,WAAS,SAAS;AAClB,uDAAyB;AAAA,IACvB;AAAA,IACA,gBAAgB;AAAA,EAClB,CAAC;AACH;AAEO,IAAM,mBAAmB,MAAM;AACpC,MAAI,CAAC,gBAAgB;AACnB,WAAO;AAAA,EACT;AAEA,MACE,eAAe,iBAAiB,UAC/B,QAAQ,IAAI,2BAA2B,QAAQ,YAAY,MAAM,SAClE;AACA,WAAO;AAAA,EACT;AAEA,SAAO;AACT;AAEO,IAAM,aAAa,YAAY;AACpC,SAAM,iDAAgB;AACxB;;;AGtRA,IAAAC,cAAsD;AAG/C,IAAI;AASJ,IAAM,aAAa,CAAC,YAA+B;AACxD,MAAI,gBAAgB;AAClB;AAAA,EACF;AAEA,MAAI,CAAC,QAAQ,SAAS;AACpB,YAAQ,UACN,QAAQ,IAAI,iBAAiB;AAAA,EACjC;AACA,MAAI,CAAC,QAAQ,QAAQ;AACnB,YAAQ,SAAS,QAAQ,IAAI;AAAA,EAC/B;AACA,MAAI,QAAQ,UAAU,OAAO,QAAQ,WAAW,UAAU;AACxD,UAAM,IAAI,oBAAoB,2BAA2B;AAAA,EAC3D;AAEA,MAAI,CAAC,QAAQ,SAAS;AACpB,YAAQ,UAAU,QAAQ,IAAI;AAAA,EAChC;AAEA,mBAAiB,OAAO,OAAO,OAAO;AAEtC,MAAI,QAAQ,UAAU;AACpB,qBAAK;AAAA,MACH,IAAI,8BAAkB;AAAA,MACtB,uBAAuB,QAAQ,QAAQ;AAAA,IACzC;AAAA,EACF;AAEA,MAAI,CAAC,QAAQ,8BAA8B;AACzC,YAAQ;AAAA,MACN,+BACE,eAAe,WAAW,sBAAsB,eAAe,OACjE;AAAA,IACF;AAAA,EACF;AAEA,eAAa,cAAc;AAC7B;AAEA,IAAM,yBAAyB,CAC7B,aACG;AACH,UAAQ,UAAU;AAAA,IAChB,KAAK;AACH,aAAO,yBAAa;AAAA,IACtB,KAAK;AACH,aAAO,yBAAa;AAAA,IACtB,KAAK;AACH,aAAO,yBAAa;AAAA,IACtB,KAAK;AACH,aAAO,yBAAa;AAAA,EACxB;AACF;;;ACnEA,IAAAC,cAAiD;AACjD,IAAAC,eAAgC;;;ACDhC,kBAA6B;AAItB,IAAM,eAAe,CAAC,OAAiC;AAC5D,SAAO,iEAAiE,KAAK,EAAE;AACjF;AAEO,IAAM,UAAU,MAAkB;AAKvC,MAAI,OAAO,WAAW,eAAe,OAAO,OAAO,eAAe,YAAY;AAC5E,WAAO,OAAO,WAAW;AAAA,EAC3B,OAAO;AACL,eAAO,YAAAC,IAAO;AAAA,EAChB;AACF;AAEO,IAAM,mBAAmB,CAAC,WAA2B;AAC1D,MAAI,KAAK,OAAO,YAAY;AAC5B,MAAI,GAAG,WAAW,IAAI,GAAG;AACvB,SAAK,GAAG,MAAM,CAAC;AAAA,EACjB;AACA,MAAI,GAAG,WAAW,IAAI;AACpB,YAAQ,KAAK,WAAW,MAAM,uEAAuE;AAAA,EACvG;AAEA,MAAI,CAAC,cAAc,KAAK,EAAE,GAAG;AAC3B,YAAQ,MAAM,WAAW,MAAM,+DAA+D;AAC9F,WAAO,QAAQ;AAAA,EACjB;AAEA,SAAO,GAAG,SAAS,IAAI,GAAG,EAAE,QAAQ,qCAAqC,gBAAgB;AAC3F;AAEO,IAAM,oBAAoB,CAAC,YAA4B;AAC5D,MAAI,KAAK,QAAQ,YAAY;AAC7B,MAAI,GAAG,WAAW,IAAI,GAAG;AACvB,SAAK,GAAG,MAAM,CAAC;AAAA,EACjB;AACA,MAAI,GAAG,WAAW,IAAI;AACpB,YAAQ,KAAK,YAAY,OAAO,wEAAwE;AAAA,EAC1G;AACA,MAAI,CAAC,cAAc,KAAK,EAAE,GAAG;AAC3B,YAAQ,MAAM,YAAY,OAAO,+DAA+D;AAChG,WAAO,QAAQ;AAAA,EACjB;AAEA,SAAO,GAAG,QAAQ,qCAAqC,gBAAgB;AACzE;AAEO,IAAM,oBAAoB,CAAC,SAAyB;AACzD,SAAO,KAAK,QAAQ,MAAM,EAAE;AAC9B;;;AD5CA,4BAAkC;AAU3B,SAAS,WAId;AAAA,EACE;AAAA,EACA;AAAA,EACA;AAAA,EACA,iBAAiB;AAAA,EACjB;AACF,GACA,IACA,YACG,MACH;AACA,MAAI,gBAAgB,oBAAQ,OAAO;AAEnC,QAAM,+BAA+B,cAAc,SAAS,0BAA0B;AAEtF,MAAI,uBAAuB;AACzB,oBAAgB,cAAc;AAAA,MAC5B;AAAA,MACA,EAAE,GAAI,sEAAgC,CAAC,GAAI,GAAG,sBAAsB;AAAA,IACtE;AAAA,EACF;AAEA,QAAM,kBAAkB,YAAY,aAAa;AACjD,QAAM,WAAW,kBAAkB,GAAG,eAAe,IAAI,IAAI,KAAK;AAClE,kBAAgB,cAAc,SAAS,eAAe,QAAQ;AAC9D,MAAI,SAAS;AACX,QAAI,aAAa,OAAO,GAAG;AACzB,YAAM,cAAc;AAAA,QAClB,SAAS,kBAAkB,OAAO;AAAA,QAClC,QAAQ,IAAI,wCAAkB,EAAE,eAAe;AAAA,QAC/C,YAAY,uBAAW;AAAA,QACvB,UAAU;AAAA,MACZ;AACA,sBAAgB,kBAAM,eAAe,eAAe,WAAW;AAAA,IACjE,OAAO;AACL,cAAQ,KAAK,oBAAoB,OAAO,oBAAoB;AAAA,IAC9D;AAAA,EACF;AAEA,MAAI,uBAAuB;AACzB,wBAAgB,8BAAgB,aAAa;AAAA,EAC/C;AAEA,SAAO,oBAAQ;AAAA,IAAK;AAAA,IAAe,MACjC,UAAU,EAAE;AAAA,MACV;AAAA,MACA,CAAC;AAAA,MACD;AAAA,MACA,OAAO,SAAe;AACpB,YAAI,WAAW,aAAa,OAAO,GAAG;AACpC,eAAK,aAAa,sBAAsB,IAAI;AAAA,QAC9C;AAEA,YAAI,iBAAiB,GAAG;AACtB,cAAI;AACF,kBAAM,QAAQ,4CAAmB;AACjC,gBACE,MAAM,WAAW,KACjB,OAAO,MAAM,CAAC,MAAM,YACpB,EAAE,MAAM,CAAC,aAAa,MACtB;AACA,mBAAK;AAAA,gBACH;AAAA,gBACA,UAAU,MAAM,CAAC,CAAC;AAAA,cACpB;AAAA,YACF,OAAO;AAGL,mBAAK;AAAA,gBACH;AAAA,gBACA,UAAU,MAAM,SAAS,IAAI,QAAQ,CAAC,CAAC;AAAA,cACzC;AAAA,YACF;AAAA,UACF,SAAS,OAAO;AACd,oBAAQ,KAAK,6BAA6B,KAAK;AAAA,UACjD;AAAA,QACF;AAGA,cAAM,EAAE,aAAa,UAAU,GAAG,KAAK,IAAI,wDAAyB,CAAC;AACrE,wBAAgB,cAAc;AAAA,UAC5B;AAAA,UACA,EAAE,GAAI,sEAAgC,CAAC,GAAI,GAAG,KAAK;AAAA,QACrD;AAEA,cAAM,MAAM,GAAG,MAAM,SAAS,IAAI;AAElC,YAAI,eAAe,SAAS;AAC1B,iBAAO,IAAI,KAAK,CAAC,gBAAgB;AAC/B,gBAAI;AACF,kBAAI,iBAAiB,GAAG;AACtB,qBAAK;AAAA,kBACH;AAAA,kBACA,UAAU,WAAW;AAAA,gBACvB;AAAA,cACF;AAAA,YACF,SAAS,OAAO;AACd,sBAAQ,KAAK,oCAAoC,KAAK;AAAA,YACxD,UAAE;AACA,mBAAK,IAAI;AAAA,YACX;AAEA,mBAAO;AAAA,UACT,CAAC;AAAA,QACH;AACA,YAAI;AACF,cAAI,iBAAiB,GAAG;AACtB,iBAAK;AAAA,cACH;AAAA,cACA,UAAU,GAAG;AAAA,YACf;AAAA,UACF;AAAA,QACF,SAAS,OAAO;AACd,kBAAQ,KAAK,8BAA8B,KAAK;AAAA,QAClD,UAAE;AACA,eAAK,IAAI;AAAA,QACX;AAEA,eAAO;AAAA,MACT;AAAA,IACF;AAAA,EACF;AACF;AAEA,SAAS,WAAW,OAAyB;AAC3C,MAAI,iBAAiB,KAAK;AACxB,WAAO,MAAM,KAAK,MAAM,QAAQ,CAAC;AAAA,EACnC,WAAW,MAAM,QAAQ,KAAK,GAAG;AAC/B,WAAO,MAAM,IAAI,CAAC,UAAU,WAAW,KAAK,CAAC;AAAA,EAC/C,WAAW,CAAC,OAAO;AACjB,WAAO;AAAA,EACT,WAAW,OAAO,UAAU,UAAU;AAEpC,UAAM,SAAc,CAAC;AACrB,WAAO,QAAQ,KAAY,EAAE,QAAQ,CAAC,CAAC,KAAK,KAAK,MAAM;AACrD,aAAO,GAAG,IAAI,WAAW,KAAK;AAAA,IAChC,CAAC;AACD,WAAO;AAAA,EACT;AAEA,SAAO;AACT;AAEA,SAAS,UAAU,OAAwB;AACzC,SAAO,KAAK,UAAU,WAAW,KAAK,CAAC;AACzC;;;ANtJA,sCAAkC;AAClC,qBAAyB;AAczB,IAAAC,yBAAkC;AAY3B,IAAM,UAAN,MAAc;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EA4CnB,OAAc,WAAW;AAAA,IACvB;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,EACF,GAA2B;AAEzB,QAAI,MAAM,wCAAiB,QAAQ,IAAI;AACvC,QAAI,QAAQ,QAAW;AACrB,YAAM,IAAI;AAAA,QACR;AAAA,MAEF;AAAA,IACF;AACA,SAAK,gBAAgB;AACrB,QAAI,mCAAS,MAAM,eAAe;AAChC,YAAM,IAAI;AAAA,QACR;AAAA,MACF;AAAA,IACF;AAEA,SAAK,cAAc,GAAG,4BAAW,qBAAqB,IAAI,8BAAY,GAAG;AACzE,SAAK,cAAc,GAAG,4BAAW,qBAAqB,IAAI,8BAAY,IAAI;AAE1E,SAAK,gBAAgB;AACrB,SAAK,MAAM,oBAAO,CAAC;AAEnB,UAAM,WAAW,IAAI,wBAAS;AAC9B,aAAS,IAAI,iBAAiB,UAAU,KAAK,aAAa,EAAE;AAC5D,UAAM,WAAW,IAAI,kDAAkB;AAAA,MACrC,KAAK,KAAK;AAAA,MACV;AAAA,IACF,CAAC;AAED,eAAoB;AAAA,MAClB;AAAA,MACA,8BAA8B;AAAA,MAC9B;AAAA,MACA,cAAc;AAAA,IAChB,CAAC;AAAA,EACH;AAAA;AAAA;AAAA;AAAA;AAAA,EAMA,OAAc,cAAuB;AACnC,WAAO,KAAK;AAAA,EACd;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAQA,OAAc,OAAO,KAA8B;AACjD,QAAI,KAAK;AACP,WAAK,MAAM;AAAA,IACb;AAAA,EACF;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAQA,OAAc,iBAAiB,eAAwB;AACrD,QAAI,eAAe;AACjB,WAAK,gBAAgB;AAAA,IACvB;AAAA,EACF;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAgBA,aAAoB,IAAI;AAAA,IACtB;AAAA,IACA;AAAA,IACA;AAAA,IACA,WAAW,CAAC;AAAA,IACZ;AAAA,IACA;AAAA,EACF,GAAqD;AACnD,UAAM,cAAc,kBAAM,cAAc;AACxC,QAAI;AACJ,QAAI;AACJ,QAAI,gBAAgB,cAAa,gCAAmB,YAAY,YAAY,CAAC,GAAG;AAC9E,qBAAe,wCAAiB,iBAAiB,YAAY,YAAY,EAAE,MAAM;AACjF,gBAAU,0CAAkB,kBAAkB,YAAY,YAAY,EAAE,OAAO;AAAA,IACjF,OAAO;AACL,qBAAe;AACf,gBAAU;AAAA,IACZ;AACA,QAAI,KAAK,kBAAkB,QAAW;AACpC,YAAM,IAAI;AAAA,QACR;AAAA,MAEF;AAAA,IACF;AACA,UAAM,eAAe,QAAQ,SAAY,KAAK,MAAM;AAEpD,UAAM,WAAW,MAAM,MAAM,GAAG,KAAK,WAAW,oBAAoB;AAAA,MAClE,QAAQ;AAAA,MACR,SAAS,KAAK,WAAW;AAAA,MACzB,MAAM,KAAK,UAAU;AAAA,QACnB;AAAA,QACA;AAAA,QACA,KAAK;AAAA,QACL;AAAA,QACA;AAAA,QACA;AAAA,MACF,CAAC;AAAA,IACH,CAAC;AAED,QAAI,CAAC,SAAS,IAAI;AAChB,YAAM,IAAI,MAAM,0BAA0B,QAAQ,eAAe,SAAS,UAAU,EAAE;AAAA,IACxF;AACA,QAAI;AACF,aAAO,MAAM,SAAS,KAAK;AAAA,IAC7B,SAAS,OAAO;AACd,YAAM,IAAI,MAAM,0CAA0C,QAAQ,YAAY,KAAK,EAAE;AAAA,IACvF;AAAA,EACF;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAiBA,OAAc,MACZ,MACA,OACA,WACA;AACA,UAAM,cAAc,kBAAM,cAAc;AACxC,QAAI,gBAAgB,UAAa,KAAC,gCAAmB,YAAY,YAAY,CAAC,GAAG;AAC/E,cAAQ;AAAA,QAAK,8DACA,IAAI;AAAA,MAEjB;AACA;AAAA,IACF;AAEA,UAAM,QAAoB;AAAA,MACxB,mBAAmB;AAAA,IACrB;AACA,QAAI,UAAU,QAAW;AACvB,YAAM,kBAAkB,IAAI;AAAA,IAC9B;AAEA,gBAAY,SAAS,MAAM,OAAO,SAAS;AAAA,EAC7C;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAkBA,OAAc,mBAAmB;AAAA,IAC/B;AAAA,IACA;AAAA,EACF,GAAqD;AACnD,UAAM,cAAc,kBAAM,cAAc;AACxC,QAAI,gBAAgB,cAAa,gCAAmB,YAAY,YAAY,CAAC,GAAG;AAC9E,UAAI,WAAW;AACb,oBAAY,aAAa,YAAY,SAAS;AAAA,MAChD;AACA,UAAI,QAAQ;AACV,oBAAY,aAAa,SAAS,MAAM;AAAA,MAC1C;AAAA,IACF;AACA,QAAI,wBAAwB,CAAC;AAC7B,QAAI,WAAW;AACb,8BAAwB,EAAE,GAAG,uBAAuB,cAAc,UAAU;AAAA,IAC9E;AACA,QAAI,QAAQ;AACV,8BAAwB,EAAE,GAAG,uBAAuB,WAAW,OAAO;AAAA,IACxE;AAEA,QAAI,gBAAgB,YAAAC,QAAW,OAAO;AACtC,UAAM,+BAA+B,cAAc,SAAS,0BAA0B;AACtF,QAAI,uBAAuB;AACzB,sBAAgB,cAAc;AAAA,QAC5B;AAAA,QACA,EAAE,GAAI,sEAAgC,CAAC,GAAI,GAAG,sBAAsB;AAAA,MACtE;AAAA,IACF;AAEA,WAAO;AAAA,EACT;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAoBA,OAAc,kBACZ,YACA;AACA,UAAM,cAAc,kBAAM,cAAc;AACxC,QAAI,gBAAgB,cAAa,gCAAmB,YAAY,YAAY,CAAC,GAAG;AAC9E,iBAAW,CAAC,KAAK,KAAK,KAAK,OAAO,QAAQ,UAAU,GAAG;AACrD,oBAAY,aAAa,KAAK,KAAK;AAAA,MACrC;AAAA,IACF;AAAA,EACF;AAAA;AAAA;AAAA;AAAA;AAAA,EAMA,OAAc,cAAc,QAAa;AACvC,QAAI,UAAU,MAAM;AAClB;AAAA,IACF;AACA,UAAM,cAAc,kBAAM,cAAc;AACxC,QAAI,gBAAgB,cAAa,gCAAmB,YAAY,YAAY,CAAC,GAAG;AAC9E,kBAAY,aAAa,aAAa,KAAK,UAAU,MAAM,CAAC;AAAA,IAC9D;AAAA,EACF;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EA4CA,OAAc,UAAU;AAAA,IACtB;AAAA,IACA;AAAA,IACA;AAAA,IACA,SAAAC;AAAA,IACA;AAAA,IACA;AAAA,EACF,GAOS;AACP,QAAI,gBAAgBA,YAAA,OAAAA,WAAW,YAAAD,QAAW,OAAO;AACjD,UAAM,kBAAkB,YAAY,aAAa;AACjD,UAAM,WAAW,kBAAkB,GAAG,eAAe,IAAI,IAAI,KAAK;AAClE,oBAAgB,cAAc,SAAS,eAAe,QAAQ;AAC9D,QAAI,SAAS;AACX,UAAI,aAAa,OAAO,GAAG;AACzB,cAAM,cAAc;AAAA,UAClB,SAAS,kBAAkB,OAAO;AAAA,UAClC,QAAQ,IAAI,yCAAkB,EAAE,eAAe;AAAA,UAC/C,YAAY,uBAAW;AAAA,UACvB,UAAU;AAAA,QACZ;AACA,wBAAgB,kBAAM,eAAe,eAAe,WAAW;AAAA,MACjE,OAAO;AACL,gBAAQ,KAAK,oBAAoB,OAAO,oBAAoB;AAAA,MAC9D;AAAA,IACF;AACA,UAAM,kBAAkB,SAAS,OAAO,QAAQ,MAAM,EAAE,OAAO,CAAC,KAAK,CAAC,KAAK,KAAK,MAAM;AACpF,UAAI,GAAG,sBAAsB,UAAU,GAAG,EAAE,IAAI;AAChD,aAAO;AAAA,IACT,GAAG,CAAC,CAA2B,IAAI,CAAC;AACpC,UAAM,aAAa;AAAA,MACjB,CAAC,SAAS,GAAG,8BAAY;AAAA,MACzB,CAAC,SAAS,GAAG;AAAA,MACb,GAAG;AAAA,IACL;AACA,UAAM,OAAO,UAAU,EAAE,UAAU,MAAM,EAAE,WAAW,GAAG,aAAa;AACtE,QAAI,SAAS;AACX,WAAK,aAAa,sBAAsB,IAAI;AAAA,IAC9C;AACA,QAAI,OAAO;AACT,WAAK,aAAa,YAAY,KAAK,UAAU,KAAK,CAAC;AAAA,IACrD;AACA,WAAO;AAAA,EACT;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAeA,OAAc,SAAY,MAAY,IAAa,WAAwB;AACzE,WAAO,YAAAA,QAAW,KAAK,kBAAM,QAAQ,YAAAA,QAAW,OAAO,GAAG,IAAI,GAAG,MAAM;AACrE,UAAG;AACD,cAAM,SAAS,GAAG;AAClB,eAAO;AAAA,MACT,UACA;AACE,YAAI,cAAc,UAAa,WAAW;AACxC,eAAK,IAAI;AAAA,QACX;AAAA,MACF;AAAA,IACF,CAAC;AAAA,EACH;AAAA,EAEA,aAAoB,WAAW;AAC7B,UAAM,WAAW;AAAA,EACnB;AAAA,EAEA,aAAoB,iBAA0B;AAAA,IAC5C;AAAA,IACA;AAAA,IACA;AAAA,EACF,GAIsC;AACpC,QAAI,OAAO;AACX,QAAI;AACF,aAAO,KAAK,UAAU;AAAA,QACpB,SAAS,4BAAW;AAAA,QACpB,MAAM,sBAAQ;AAAA,QACd,QAAQ;AAAA,MACV,CAAC;AAAA,IACH,SAAS,OAAO;AACd,YAAM,IAAI,MAAM,2CAA2C,IAAI,YAAY,KAAK,EAAE;AAAA,IACpF;AACA,UAAM,WAAW,MAAM,MAAM,GAAG,KAAK,WAAW,mBAAmB;AAAA,MACjE,QAAQ;AAAA,MACR,SAAS,KAAK,WAAW;AAAA,MACzB;AAAA,IACF,CAAC;AAED,QAAI,CAAC,SAAS,IAAI;AAChB,YAAM,IAAI,MAAM,+BAA+B,IAAI,eAAe,SAAS,UAAU,EAAE;AAAA,IACzF;AAEA,WAAO,MAAM,SAAS,KAAK;AAAA,EAC7B;AAAA,EAEA,aAAoB,cAAoB;AAAA,IACtC;AAAA,IACA;AAAA,IACA;AAAA,EACF,GAIyC;AACvC,UAAM,SAAS,IAAI,gBAAgB;AAAA,MACjC,MAAM;AAAA,MACN,QAAQ,OAAO,SAAS;AAAA,MACxB,OAAO,MAAM,SAAS;AAAA,IACxB,CAAC;AACD,UAAM,WAAW,MAAM,MAAM,GAAG,KAAK,WAAW,2BAA2B,OAAO,SAAS,CAAC,IAAI;AAAA,MAC9F,QAAQ;AAAA,MACR,SAAS,KAAK,WAAW;AAAA,IAC3B,CAAC;AAED,QAAI,CAAC,SAAS,IAAI;AAChB,YAAM,IAAI,MAAM,wCAAwC,WAAW,eAAe,SAAS,UAAU,EAAE;AAAA,IACzG;AAEA,WAAO,MAAM,SAAS,KAAK;AAAA,EAC7B;AAAA,EAEA,OAAe,aAAa;AAC1B,WAAO;AAAA,MACL,gBAAgB;AAAA,MAChB,iBAAiB,UAAU,KAAK,aAAa;AAAA,IAC/C;AAAA,EACF;AACF;AAtfa,QAII,MAA8B,CAAC;AAJnC,QAKI,gBAAyB;;;AQlD1C,0BAAwB;;;ACCxB,IAAM,qBAAqB;AAEpB,IAAe,oBAAf,MAAuC;AAAA,EAC5C,MAAa,MAAM,OAAe,KAAyC;AACzE,UAAM,SAAS,CAAC;AAChB,aAAS,IAAI,KAAK,IAAI,OAAO,CAAC,GAAG,IAAI,KAAK,IAAI,KAAK,MAAM,KAAK,KAAK,CAAC,GAAG,KAAK;AAC1E,aAAO,KAAK,MAAM,KAAK,IAAI,CAAC,CAAC;AAAA,IAC/B;AACA,WAAO;AAAA,EACT;AAGF;AAEO,IAAM,iBAAN,cAAmC,kBAAwB;AAAA,EAOhE,YAAY,MAAc,WAAoB;AAC5C,UAAM;AAPR,SAAQ,eAAkC,CAAC;AAC3C,SAAQ,MAAqB;AAC7B,SAAQ,SAAiB;AAMvB,SAAK,OAAO;AACZ,SAAK,YAAY,aAAa;AAAA,EAChC;AAAA,EAEA,MAAc,aAAa;AAGzB,UAAM,OAAO,MAAM,QAAE,cAAoB;AAAA,MACvC,aAAa,KAAK;AAAA,MAClB,QAAQ,KAAK;AAAA,MACb,OAAO,KAAK;AAAA,IACd,CAAC;AACD,SAAK,eAAe,KAAK,aAAa,OAAO,KAAK,KAAK;AACvD,SAAK,SAAS,KAAK,aAAa;AAChC,QAAI,KAAK,QAAQ,MAAM;AACrB,WAAK,MAAM,KAAK;AAAA,IAClB;AAAA,EACF;AAAA,EAEA,MAAa,OAAwB;AACnC,QAAI,KAAK,QAAQ,MAAM;AACrB,YAAM,KAAK,WAAW;AAAA,IACxB;AACA,WAAO,KAAK;AAAA,EACd;AAAA,EACA,MAAa,IAAI,OAAyC;AACxD,QAAI,SAAS,KAAK,aAAa,QAAQ;AACrC,YAAM,KAAK,WAAW;AAAA,IACxB;AACA,WAAO,KAAK,aAAa,KAAK;AAAA,EAChC;AACF;;;ACzDA,IAAAE,cAAiD;AAqCjD,eAAsB,QACpB;AAAA,EACE;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACF,GAAmB,OAAU,MAAiC;AAC9D,MAAI,OAAO,UAAa,OAAO,OAAO,YAAY;AAChD,UAAM,IAAI,MAAM,mEAAmE;AAAA,EACrF;AAEA,MAAI,wBAAwB,CAAC;AAC7B,MAAI,WAAW;AACb,4BAAwB,EAAE,GAAG,uBAAuB,cAAc,UAAU;AAAA,EAC9E;AACA,MAAI,QAAQ;AACV,4BAAwB,EAAE,GAAG,uBAAuB,WAAW,OAAO;AAAA,EACxE;AACA,MAAI,WAAW;AACb,4BAAwB,EAAE,GAAG,uBAAuB,cAAc,UAAU;AAAA,EAC9E;AACA,MAAI,UAAU;AACZ,4BAAwB,EAAE,GAAG,uBAAuB,aAAa,SAAS;AAAA,EAC5E;AAEA,SAAO,MAAM,WAAiB;AAAA,IAC5B,MAAM,sBAAQ,GAAG;AAAA,IACjB;AAAA,IACA;AAAA,EACF,GAAG,IAAI,QAAW,GAAG,IAAI;AAC3B;AAwBO,SAAS,WACd,QACA,OACG,MACY;AAjGjB;AAkGE,MAAI,gBAAgB,oBAAQ,OAAO;AACnC,QAAM,gCAA+B,mBAAc,SAAS,0BAA0B,MAAjD,YAAsD,CAAC;AAC5F,QAAM,kBAAkB,OAAO,QAAQ,MAAM,EAAE,OAAO,CAAC,KAAK,CAAC,KAAK,KAAK,MAAM;AAC3E,QAAI,SAAS,GAAG,EAAE,IAAI;AACtB,WAAO;AAAA,EACT,GAAG,CAAC,CAA2B;AAE/B,kBAAgB,cAAc;AAAA,IAC5B;AAAA,IACA,EAAE,GAAG,8BAA8B,GAAG,gBAAgB;AAAA,EACxD;AAEA,QAAM,SAAS,oBAAQ,KAAK,eAAe,MAAM;AAC/C,WAAO,GAAG,MAAM,QAAW,IAAI;AAAA,EACjC,CAAC;AAED,QAAM,4BAA4B,mBAAc,SAAS,0BAA0B,MAAjD,YAAsD,CAAC;AACzF,aAAW,CAAC,KAAK,KAAK,KAAK,OAAO,QAAQ,eAAe,GAAG;AAC1D,WAAO,yBAAyB,SAAS,GAAG,EAAE;AAAA,EAChD;AAEA,kBAAgB,cAAc;AAAA,IAC5B;AAAA,IACA;AAAA,EACF;AAEA,SAAO;AACT;;;AFvHA,IAAAC,cAAsB;AAItB,IAAM,qBAAqB;AAQ3B,IAAM,mBAAmB,CAAC,WAAmB,iBAAyB;AACpE,SAAO,+BAA+B,SAAS,gBAAgB,YAAY;AAC7E;AAEA,IAAM,mBACJ,CAAU,YAAoE;AAC5E,QAAM,iBAA2C,CAAC;AAClD,aAAW,UAAU,SAAS;AAC5B,eAAW,OAAO,OAAO,QAAQ;AAC/B,UAAI,eAAe,GAAG,GAAG;AACvB,uBAAe,GAAG,EAAE,KAAK,OAAO,OAAO,GAAG,CAAC;AAAA,MAC7C,OAAO;AACL,uBAAe,GAAG,IAAI,CAAC,OAAO,OAAO,GAAG,CAAC;AAAA,MAC3C;AAAA,IACF;AAAA,EACF;AAEA,QAAM,gBAAwC,CAAC;AAC/C,aAAW,OAAO,gBAAgB;AAChC,kBAAc,GAAG,IAAI,eAAe,GAAG,EAAE,OAAO,CAAC,GAAG,MAAM,IAAI,GAAG,CAAC,IAC9D,eAAe,GAAG,EAAE;AAAA,EAC1B;AAEA,SAAO;AACT;AAqEK,IAAM,iBAAN,MAAqB;AAAA,EAG1B,YAAY,WAAmB;AAC7B,SAAK,YAAY;AAAA,EACnB;AACF;AA6CA,IAAM,qBAAN,MAAyB;AAAA,EAOvB,cAAc;AANd,SAAQ,cAAqC,IAAI,oBAAAC,QAAY;AAAA,MAC3D,CAAC;AAAA,MACD,oBAAAA,QAAY,QAAQ;AAAA,IACtB;AACA,SAAQ,kBAA0B;AAAA,EAElB;AAAA,EAET,MAAM,EAAE,OAAO,GAAuB;AAC3C,SAAK,YAAY,MAAM,QAAQ,CAAC;AAAA,EAClC;AAAA,EAEO,OAAO,aAAqB;AACjC,SAAK,mBAAmB;AACxB,SAAK,YAAY,OAAO,KAAK,eAAe;AAAA,EAC9C;AAAA;AAAA,EAGO,cAAc,OAAc;AACjC,SAAK,YAAY,KAAK;AACtB,YAAQ,OAAO,MAAM;AAAA,SAAY,MAAM,OAAO;AAAA,CAAI;AAAA,EACpD;AAAA;AAAA,EAGO,KAAK;AAAA,IACV;AAAA,IACA;AAAA,IACA;AAAA,EACF,GAAuF;AACrF,SAAK,YAAY,KAAK;AACtB,YAAQ,OAAO,MAAM;AAAA,mBAAsB,iBAAiB,WAAW,YAAY,CAAC;AAAA,CAAI;AACxF,YAAQ,OAAO,MAAM,qBAAqB;AAC1C,eAAW,OAAO,eAAe;AAC/B,cAAQ,OAAO,MAAM,GAAG,GAAG,KAAK,KAAK,UAAU,cAAc,GAAG,CAAC,CAAC;AAAA,CAAI;AAAA,IACxE;AACA,YAAQ,OAAO,MAAM,IAAI;AAAA,EAC3B;AACF;AAEA,IAAM,aAAN,MAA0B;AAAA,EAWxB,YAAY;AAAA,IACV;AAAA,IAAM;AAAA,IAAU;AAAA,IAAY;AAAA,IAAiB;AAAA,IAAS;AAAA,IAAM;AAAA,EAC9D,GAAwC;AAZxC,SAAQ,aAAsB;AAQ9B,SAAQ,YAAoB;AAnN9B;AAwNI,QAAI,OAAO,KAAK,UAAU,EAAE,WAAW,GAAG;AACxC,YAAM,IAAI,MAAM,wBAAwB;AAAA,IAC1C;AAEA,UAAM,qBAAqB;AAE3B,eAAW,OAAO,YAAY;AAC5B,UAAI,CAAC,mBAAmB,KAAK,GAAG,GAAG;AACjC,cAAM,IAAI;AAAA,UACR,2BAA2B,GAAG;AAAA,QAEhC;AAAA,MACF;AAAA,IACF;AAEA,SAAK,mBAAmB,IAAI,mBAAmB;AAC/C,SAAK,OAAO;AACZ,SAAK,WAAW;AAChB,SAAK,aAAa;AAClB,SAAK,kBAAkB;AACvB,SAAK,UAAU;AACf,SAAK,OAAO;AACZ,QAAI,QAAQ;AACV,WAAK,aAAY,YAAO,cAAP,YAAoB;AAAA,IACvC;AACA,YAAQ,WAAW;AAAA,MACjB,eAAe,iCAAQ;AAAA,MACvB,SAAS,iCAAQ;AAAA,MACjB,UAAU,iCAAQ;AAAA,MAClB,UAAU,iCAAQ;AAAA,MAClB,mBAAmB,iCAAQ;AAAA,IAC7B,CAAC;AAAA,EACH;AAAA,EAEA,MAAa,MAAqB;AAChC,QAAI,KAAK,YAAY;AACnB,YAAM,IAAI,MAAM,gCAAgC;AAAA,IAClD;AAEA,SAAK,iBAAiB,MAAM,EAAE,QAAQ,MAAM,KAAK,UAAU,EAAE,CAAC;AAC9D,QAAI;AACJ,QAAI;AACF,yBAAmB,MAAM,KAAK,kBAAkB;AAAA,IAClD,SAAS,GAAG;AACV,WAAK,iBAAiB,cAAc,CAAU;AAC9C,WAAK,aAAa;AAClB;AAAA,IACF;AAEA,UAAM,aAAa,MAAM,QAAQ,iBAAiB;AAAA,MAChD,SAAS,KAAK;AAAA,MACd,MAAM,KAAK;AAAA,MACX,MAAM;AAAA,IACR,CAAC;AACD,UAAM,gBAAgB,iBAAiB,gBAAgB;AACvD,SAAK,iBAAiB,KAAK;AAAA,MACzB;AAAA,MACA,WAAW,WAAW;AAAA,MACtB,cAAc,WAAW;AAAA,IAC3B,CAAC;AACD,SAAK,aAAa;AAElB,UAAM,QAAQ,SAAS;AAAA,EACzB;AAAA,EAEA,MAAa,oBAA6D;AACxE,UAAM,mBAAmD,CAAC;AAC1D,aAAS,IAAI,GAAG,IAAI,MAAM,KAAK,UAAU,GAAG,KAAK,KAAK,WAAW;AAC/D,YAAM,QAAQ,MAAM,KAAK,KAAK,MAAM,GAAG,IAAI,KAAK,SAAS;AACzD,YAAM,kBAAkB,MAAM,KAAK,cAAc,KAAK;AACtD,uBAAiB,KAAK,GAAG,eAAe;AACxC,WAAK,iBAAiB,OAAO,MAAM,MAAM;AAAA,IAC3C;AACA,WAAO;AAAA,EACT;AAAA,EAEA,MAAc,cAAc,OAAmE;AAC7F,UAAM,gBAAgB,MAAM,IAAI,OAAO,cAAc;AACnD,UAAI;AAIJ,YAAM,QAAQ,EAAE,MAAM,cAAc,WAAW,aAAa,GAAG,YAAY;AACzE,0BAAM,cAAc,EAAG,aAAa,WAAW,YAAY;AAE3D,cAAM,EAAE,QAAQ,eAAe,IAAI,MAAM;AAAA,UACvC,EAAE,MAAM,WAAW;AAAA,UACnB,OAAO,SAAY;AACjB,kBAAMC,kBAAiB,kBAAM,cAAc,EAAG,YAAY,EAAE;AAC5D,8BAAM,cAAc,EAAG,aAAa,WAAW,UAAU;AACzD,mBAAO;AAAA,cACL,QAAQ,MAAM,KAAK,SAAS,IAAI;AAAA,cAChC,gBAAgB,iBAAiBA,eAAc;AAAA,YACjD;AAAA,UACF;AAAA,UACA,UAAU;AAAA,QACZ;AACA,cAAM,SAAS,UAAU;AAEzB,YAAI,SAAiC,CAAC;AACtC,mBAAW,CAAC,eAAe,SAAS,KAAK,OAAO,QAAQ,KAAK,UAAU,GAAG;AACxE,gBAAM,QAAQ,MAAM;AAAA,YAClB,EAAE,MAAM,cAAc;AAAA,YACtB,OAAOC,SAAWC,YAAe;AAC/B,gCAAM,cAAc,EAAG,aAAa,WAAW,WAAW;AAC1D,qBAAO,MAAM,UAAUD,SAAQC,OAAM;AAAA,YACvC;AAAA,YACA;AAAA,YACA;AAAA,UACF;AAEA,cAAI,OAAO,UAAU,UAAU;AAC7B,gBAAI,MAAM,KAAK,GAAG;AAChB,oBAAM,IAAI,MAAM,aAAa,aAAa,eAAe;AAAA,YAC3D;AACA,mBAAO,aAAa,IAAI;AAAA,UAC1B,OAAO;AACL,qBAAS,EAAE,GAAG,QAAQ,GAAG,MAAM;AAAA,UACjC;AAAA,QACF;AAEA,cAAM;AAAA,UACJ,gBAAgB;AAAA,UAChB,MAAM,UAAU;AAAA,UAChB;AAAA,UACA;AAAA,UACA,SAAS,kBAAkB,kBAAM,cAAc,EAAG,YAAY,EAAE,OAAO;AAAA;AAAA;AAAA;AAAA,UAIvE,iBAAiB,KAAK;AAAA,UACtB;AAAA,QACF;AAAA,MACF,CAAC;AAED,aAAO;AAAA,IACT,CAAC;AAED,UAAM,UAAU,MAAM,QAAQ,IAAI,aAAa;AAE/C,WAAO;AAAA,EACT;AAAA,EAEA,MAAc,YAA6B;AACzC,WAAO,KAAK,gBAAgB,oBAAoB,MAAM,KAAK,KAAK,KAAK,IAAI,KAAK,KAAK;AAAA,EACrF;AACF;AAuBA,eAAsB,SAAkB;AAAA,EACtC;AAAA,EAAM;AAAA,EAAU;AAAA,EAAY;AAAA,EAAiB;AAAA,EAAS;AAAA,EAAM;AAC9D,GAAuD;AACrD,QAAM,aAAa,IAAI,WAAW;AAAA,IAChC;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,EACF,CAAC;AACD,MAAI,WAAW,wBAAwB;AACrC,eAAW,cAAc;AAAA,EAC3B,OAAO;AACL,UAAM,WAAW,IAAI;AAAA,EACvB;AACF;;;ATpYA,IAAAC,cAAqB;","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"]}
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 * DEPRECATED: use `withSession` and/or `withMetadata` instead.\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 console.warn(\"Laminar().contextWithSession() is deprecated. Use withSession() instead.\");\n const currentSpan = trace.getActiveSpan();\n if (currentSpan !== undefined && isSpanContextValid(currentSpan.spanContext())) {\n if (sessionId) {\n currentSpan.setAttribute(SESSION_ID, JSON.stringify(sessionId));\n }\n if (userId) {\n currentSpan.setAttribute(USER_ID, JSON.stringify(userId));\n }\n }\n let associationProperties = {};\n if (sessionId) {\n associationProperties = { ...associationProperties, \"session_id\": JSON.stringify(sessionId) };\n }\n if (userId) {\n associationProperties = { ...associationProperties, \"user_id\": JSON.stringify(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 * Sets the session information for the current span and returns the\n * context to use for the following spans. Returns the result of the\n * function execution, so can be used in an `await` statement.\n * \n * @param sessionId - The session ID to associate with the context.\n * @param fn - Function to execute within the session context.\n * @returns The result of the function execution.\n * \n * @example\n * import { Laminar, observe } from '@lmnr-ai/lmnr';\n * const result = await Laminar.withSession(\"session1234\", async () => {\n * // Your code here\n * });\n */\n public static withSession<T>(\n sessionId: string,\n fn: () => T,\n ) {\n const currentSpan = trace.getActiveSpan();\n if (currentSpan !== undefined && isSpanContextValid(currentSpan.spanContext())) {\n if (sessionId) {\n currentSpan.setAttribute(SESSION_ID, JSON.stringify(sessionId));\n }\n }\n let associationProperties = {};\n if (sessionId) {\n associationProperties = { ...associationProperties, \"session_id\": JSON.stringify(sessionId) };\n }\n\n let entityContext = contextApi.active();\n const currentAssociationProperties = entityContext.getValue(ASSOCIATION_PROPERTIES_KEY);\n if (associationProperties && Object.keys(associationProperties).length > 0) {\n entityContext = entityContext.setValue(\n ASSOCIATION_PROPERTIES_KEY,\n { ...(currentAssociationProperties ?? {}), ...associationProperties },\n );\n }\n return contextApi.with(entityContext, fn);\n }\n\n /**\n * Sets the metadata for the current span and returns the context to use for\n * the following spans. Returns the result of the function execution, so can\n * be used in an `await` statement.\n * \n * @param metadata - The metadata to associate with the context. Will be sent\n * as attributes, so must be serializable to JSON.\n * @param fn - Function to execute within the metadata context.\n * @returns The result of the function execution.\n * \n * @example\n * import { Laminar } from '@lmnr-ai/lmnr';\n * const result = await Laminar.withMetadata(\n * {\n * \"my_metadata_key\": \"my_metadata_value\"\n * },\n * async () => {\n * // Your code here\n * }\n * );\n */\n public static withMetadata<T>(\n metadata: Record<string, any>,\n fn: () => T,\n ) {\n const currentSpan = trace.getActiveSpan();\n if (currentSpan !== undefined && isSpanContextValid(currentSpan.spanContext())) {\n for (const [key, value] of Object.entries(metadata)) {\n currentSpan.setAttribute(`${ASSOCIATION_PROPERTIES}.metadata.${key}`, JSON.stringify(value));\n }\n }\n let metadataAttributes = {};\n for (const [key, value] of Object.entries(metadata)) {\n metadataAttributes = { ...metadataAttributes, [`metadata.${key}`]: JSON.stringify(value) };\n }\n\n let entityContext = contextApi.active();\n const currentAssociationProperties = entityContext.getValue(ASSOCIATION_PROPERTIES_KEY);\n if (metadataAttributes && Object.keys(metadataAttributes).length > 0) {\n entityContext = entityContext.setValue(\n ASSOCIATION_PROPERTIES_KEY,\n { ...(currentAssociationProperties ?? {}), ...metadataAttributes },\n );\n }\n return contextApi.with(entityContext, fn);\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, JSON.stringify(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":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;;ACOA,IAAAA,cAUO;;;ACdA,IAAM,WAAW;AAAA,EACtB,SAAS;AAAA,EACT,OAAO;AAAA,EACP,UAAU;AACZ;AAOO,IAAM,iBAAN,cAA6B,MAAM;AAAA,EAUxC,YAAY,SAAiB,WAAqB,SAAS,OAAO;AAChE,UAAM,OAAO;AACb,SAAK,WAAW;AAAA,EAClB;AACF;AAWO,IAAM,sBAAN,cAAkC,eAAe;AAAA,EACtD,YAAY,SAAkB,OAAe;AAC3C,UAAM,4BAAW,sCAAsC,SAAS,QAAQ;AACxE,SAAK,kBAAkB;AAAA,EACzB;AACF;;;AC3CA,kBAA6B;AAC7B,IAAAC,cAAoC;AACpC,uCAAkC;;;ACHlC,iBAAwC;AAGxC,IAAM,cAAc;AACb,IAAM,oBAAgB,6BAAiB,WAAW;AAClD,IAAM,iCAA6B;AAAA,EACxC;AACF;AAEO,IAAM,YAAY,MAAM;AAC7B,SAAO,iBAAM,UAAU,WAAW;AACpC;AAEO,IAAM,cAAc,CAAC,kBAA+C;AACzE,QAAM,OAAO,cAAc,SAAS,aAAa;AAEjD,SAAO,OAAO,GAAG,IAAI,KAAK;AAC5B;;;ADNA,4BAA4E;AAC5E,6BAAyC;AACzC,uCAAyC;AACzC,oCAAsC;AACtC,mCAA2C;AAC3C,wCAA0C;AAC1C,sCAGO;AACP,qCAAuC;AACvC,oCAAsC;AACtC,sCAAwC;AACxC,uCAAyC;AACzC,sCAAwC;AACxC,oCAAsC;;;AE1BtC,qCAA+B;AAExB,IAAM,aAAa;AACnB,IAAM,cAAc;AACpB,IAAM,YAAY;AAClB,IAAM,YAAY;AAClB,IAAM,8BAA8B;AACpC,IAAM,uBAAuB;AAE7B,IAAM,yBAAyB;AAC/B,IAAM,aAAa;AACnB,IAAM,UAAU;AAGhB,IAAM,mCAA2D;AAAA,EACtE,aAAa;AACf;AAEO,IAAM,oBAAoB;AAAA;AAAA;AAAA;AAAA,EAI/B,mBAAmB;AAAA;AAAA,EAEnB,oBAAoB;AAAA,EACpB,mBAAmB,8CAAe;AAAA,EAClC,UAAU,8CAAe;AAAA,EACzB,eAAe,8CAAe;AAAA,EAC9B,gBAAgB,8CAAe;AAAA;AAAA;AAAA;AAAA;AAAA,EAK/B,YAAY;AAAA,EACZ,aAAa;AAAA,EACb,YAAY;AAAA;AAAA;AAGd;;;AFTA,IAAI;AACJ,IAAI;AACJ,IAAI;AACJ,IAAI;AACJ,IAAI;AACJ,IAAI;AACJ,IAAI;AACJ,IAAI;AACJ,IAAI;AACJ,IAAI;AACJ,IAAI;AACJ,IAAI;AACJ,IAAI;AAGJ,IAAM,mBAAsC,CAAC;AAE7C,IAAM,uBAAuB,MAAM;AACjC,QAAM,eAAe;AAErB,0BAAwB,IAAI,oDAAsB;AAAA,IAChD;AAAA,EACF,CAAC;AACD,mBAAiB,KAAK,qBAAqB;AAE3C,6BAA2B,IAAI,0DAAyB;AACxD,mBAAiB,KAAK,wBAAwB;AAE9C,+BAA6B,IAAI,wDAA2B;AAC5D,mBAAiB,KAAK,0BAA0B;AAEhD,0BAAwB,IAAI,oDAAsB;AAClD,mBAAiB,KAAK,qBAAqB;AAE3C,4BAA0B,IAAI,wDAAwB;AACtD,mBAAiB,KAAK,uBAAuB;AAE7C,8BAA4B,IAAI,0DAA0B;AAC1D,mBAAiB,KAAK,yBAAyB;AAE/C,2BAAyB,IAAI,sDAAuB;AACpD,mBAAiB,KAAK,sBAAsB;AAE5C,4BAA0B,IAAI,wDAAwB;AACtD,mBAAiB,KAAK,uBAAuB;AAE7C,6BAA2B,IAAI,0DAAyB;AACxD,mBAAiB,KAAK,wBAAwB;AAE9C,8BAA4B,IAAI,4DAA0B;AAC1D,mBAAiB,KAAK,yBAAyB;AAE/C,4BAA0B,IAAI,wDAAwB;AACtD,mBAAiB,KAAK,uBAAuB;AAE7C,0BAAwB,IAAI,oDAAsB;AAClD,mBAAiB,KAAK,qBAAqB;AAC7C;AAEA,IAAM,+BAA+B,CACnC,sBACG;AACH,QAAM,eAAe;AAErB,mBAAiB,SAAS;AAE1B,MAAI,uDAAmB,QAAQ;AAC7B,4BAAwB,IAAI,oDAAsB;AAAA,MAChD;AAAA,IACF,CAAC;AACD,qBAAiB,KAAK,qBAAqB;AAC3C,0BAAsB,mBAAmB,kBAAkB,MAAM;AAAA,EACnE;AAEA,MAAI,uDAAmB,WAAW;AAChC,+BAA2B,IAAI,0DAAyB;AACxD,qBAAiB,KAAK,wBAAwB;AAC9C,6BAAyB,mBAAmB,kBAAkB,SAAS;AAAA,EACzE;AAEA,MAAI,uDAAmB,aAAa;AAClC,UAAM,kBAAkB,IAAI,wDAA2B;AACvD,qBAAiB,KAAK,eAAkC;AACxD,iCAA6B;AAC7B,oBAAgB,mBAAmB,kBAAkB,WAAW;AAAA,EAClE;AAEA,MAAI,uDAAmB,QAAQ;AAC7B,4BAAwB,IAAI,oDAAsB;AAClD,qBAAiB,KAAK,qBAAqB;AAC3C,0BAAsB,mBAAmB,kBAAkB,MAAM;AAAA,EACnE;AAEA,MAAI,uDAAmB,iBAAiB;AACtC,8BAA0B,IAAI,wDAAwB;AACtD,qBAAiB,KAAK,uBAAuB;AAC7C,4BAAwB;AAAA,MACtB,kBAAkB;AAAA,IACpB;AAAA,EACF;AAEA,MAAI,uDAAmB,mBAAmB;AACxC,gCAA4B,IAAI,0DAA0B;AAC1D,qBAAiB,KAAK,yBAAyB;AAC/C,8BAA0B;AAAA,MACxB,kBAAkB;AAAA,IACpB;AAAA,EACF;AAEA,MAAI,uDAAmB,SAAS;AAC9B,6BAAyB,IAAI,sDAAuB;AACpD,qBAAiB,KAAK,sBAAsB;AAC5C,2BAAuB,mBAAmB,kBAAkB,OAAO;AAAA,EACrE;AAEA,MAAI,uDAAmB,UAAU;AAC/B,UAAM,kBAAkB,IAAI,wDAAwB;AACpD,qBAAiB,KAAK,eAAkC;AACxD,oBAAgB,mBAAmB,kBAAkB,QAAQ;AAAA,EAC/D;AAEA,MAAI,uDAAmB,WAAW;AAChC,+BAA2B,IAAI,0DAAyB;AACxD,qBAAiB,KAAK,wBAAwB;AAC9C,6BAAyB,mBAAmB,kBAAkB,SAAS;AAAA,EACzE;AAEA,MAAI,uDAAmB,YAAY;AACjC,gCAA4B,IAAI,4DAA0B;AAC1D,qBAAiB,KAAK,yBAAyB;AAC/C,8BAA0B,mBAAmB,kBAAkB,UAAU;AAAA,EAC3E;AAEA,MAAI,uDAAmB,UAAU;AAC/B,8BAA0B,IAAI,wDAAwB;AACtD,qBAAiB,KAAK,uBAAuB;AAC7C,4BAAwB,mBAAmB,kBAAkB,QAAQ;AAAA,EACvE;AAEA,MAAI,uDAAmB,QAAQ;AAC7B,4BAAwB,IAAI,oDAAsB;AAClD,qBAAiB,KAAK,qBAAqB;AAC3C,0BAAsB,mBAAmB,kBAAkB,MAAM;AAAA,EACnE;AACF;AAQO,IAAM,eAAe,CAAC,YAA+B;AArL5D;AAsLE,MAAI,QAAQ,sBAAsB,QAAW;AAG3C,iCAA6B,QAAQ,iBAAiB;AAAA,EACxD,OAAO;AACL,yBAAqB;AAAA,EACvB;AAEA,MAAI,CAAC,iBAAiB,GAAG;AACvB,mEAAuB,UAAU;AAAA,MAC/B,cAAc;AAAA,IAChB;AACA,6EAA4B,UAAU;AAAA,MACpC,cAAc;AAAA,IAChB;AACA,2EAA2B,UAAU;AAAA,MACnC,cAAc;AAAA,IAChB;AACA,uEAAyB,UAAU;AAAA,MACjC,cAAc;AAAA,IAChB;AACA,2EAA2B,UAAU;AAAA,MACnC,cAAc;AAAA,IAChB;AACA,qEAAwB,UAAU;AAAA,MAChC,cAAc;AAAA,IAChB;AACA,mEAAuB,UAAU;AAAA,MAC/B,cAAc;AAAA,IAChB;AACA,uEAAyB,UAAU;AAAA,MACjC,cAAc;AAAA,IAChB;AAAA,EACF;AAEA,QAAM,UAAU,QAAQ,IAAI,oBACxB,yBAAa,wBAAwB,QAAQ,IAAI,iBAAiB,IAClE,EAAE,eAAe,UAAU,QAAQ,MAAM,GAAG;AAEhD,QAAM,iBACJ,aAAQ,aAAR,YACA,IAAI,mDAAkB;AAAA,IACpB,KAAK,GAAG,QAAQ,OAAO;AAAA,IACvB;AAAA,EACF,CAAC;AACH,mBAAiB,QAAQ,eACrB,IAAI,0CAAoB,aAAa,IACrC,IAAI,yCAAmB,aAAa;AAExC,iBAAe,UAAU,CAAC,SAAe;AACvC,UAAM,WAAW,oBAAQ,OAAO,EAAE,SAAS,aAAa;AACxD,QAAI,UAAU;AACZ,WAAK,aAAa,WAAW,QAAkB;AAAA,IACjD;AAEA,SAAK,aAAa,6BAA6B,YAAY;AAG3D,UAAM,wBAAwB,oBAC3B,OAAO,EACP,SAAS,0BAA0B;AACtC,QAAI,uBAAuB;AACzB,iBAAW,CAAC,KAAK,KAAK,KAAK,OAAO,QAAQ,qBAAqB,GAAG;AAChE,YAAI,OAAO,KAAK,gCAAgC,EAAE,SAAS,GAAG,GAAG;AAC/D,eAAK,aAAa,iCAAiC,GAAG,GAAG,KAAK;AAAA,QAChE,OAAO;AACL,eAAK,aAAa,GAAG,sBAAsB,IAAI,GAAG,IAAI,KAAK;AAAA,QAC7D;AAAA,MACF;AAAA,IACF;AAAA,EACF;AAEA,QAAM,WAAW,IAAI,yCAAmB;AACxC,WAAS,iBAAiB,cAAc;AACxC,WAAS,SAAS;AAClB,uDAAyB;AAAA,IACvB;AAAA,IACA,gBAAgB;AAAA,EAClB,CAAC;AACH;AAEO,IAAM,mBAAmB,MAAM;AACpC,MAAI,CAAC,gBAAgB;AACnB,WAAO;AAAA,EACT;AAEA,MACE,eAAe,iBAAiB,UAC/B,QAAQ,IAAI,2BAA2B,QAAQ,YAAY,MAAM,SAClE;AACA,WAAO;AAAA,EACT;AAEA,SAAO;AACT;AAEO,IAAM,aAAa,YAAY;AACpC,SAAM,iDAAgB;AACxB;;;AGtRA,IAAAC,cAAsD;AAG/C,IAAI;AASJ,IAAM,aAAa,CAAC,YAA+B;AACxD,MAAI,gBAAgB;AAClB;AAAA,EACF;AAEA,MAAI,CAAC,QAAQ,SAAS;AACpB,YAAQ,UACN,QAAQ,IAAI,iBAAiB;AAAA,EACjC;AACA,MAAI,CAAC,QAAQ,QAAQ;AACnB,YAAQ,SAAS,QAAQ,IAAI;AAAA,EAC/B;AACA,MAAI,QAAQ,UAAU,OAAO,QAAQ,WAAW,UAAU;AACxD,UAAM,IAAI,oBAAoB,2BAA2B;AAAA,EAC3D;AAEA,MAAI,CAAC,QAAQ,SAAS;AACpB,YAAQ,UAAU,QAAQ,IAAI;AAAA,EAChC;AAEA,mBAAiB,OAAO,OAAO,OAAO;AAEtC,MAAI,QAAQ,UAAU;AACpB,qBAAK;AAAA,MACH,IAAI,8BAAkB;AAAA,MACtB,uBAAuB,QAAQ,QAAQ;AAAA,IACzC;AAAA,EACF;AAEA,MAAI,CAAC,QAAQ,8BAA8B;AACzC,YAAQ;AAAA,MACN,+BACE,eAAe,WAAW,sBAAsB,eAAe,OACjE;AAAA,IACF;AAAA,EACF;AAEA,eAAa,cAAc;AAC7B;AAEA,IAAM,yBAAyB,CAC7B,aACG;AACH,UAAQ,UAAU;AAAA,IAChB,KAAK;AACH,aAAO,yBAAa;AAAA,IACtB,KAAK;AACH,aAAO,yBAAa;AAAA,IACtB,KAAK;AACH,aAAO,yBAAa;AAAA,IACtB,KAAK;AACH,aAAO,yBAAa;AAAA,EACxB;AACF;;;ACnEA,IAAAC,cAAiD;AACjD,IAAAC,eAAgC;;;ACDhC,kBAA6B;AAItB,IAAM,eAAe,CAAC,OAAiC;AAC5D,SAAO,iEAAiE,KAAK,EAAE;AACjF;AAEO,IAAM,UAAU,MAAkB;AAKvC,MAAI,OAAO,WAAW,eAAe,OAAO,OAAO,eAAe,YAAY;AAC5E,WAAO,OAAO,WAAW;AAAA,EAC3B,OAAO;AACL,eAAO,YAAAC,IAAO;AAAA,EAChB;AACF;AAEO,IAAM,mBAAmB,CAAC,WAA2B;AAC1D,MAAI,KAAK,OAAO,YAAY;AAC5B,MAAI,GAAG,WAAW,IAAI,GAAG;AACvB,SAAK,GAAG,MAAM,CAAC;AAAA,EACjB;AACA,MAAI,GAAG,WAAW,IAAI;AACpB,YAAQ,KAAK,WAAW,MAAM,uEAAuE;AAAA,EACvG;AAEA,MAAI,CAAC,cAAc,KAAK,EAAE,GAAG;AAC3B,YAAQ,MAAM,WAAW,MAAM,+DAA+D;AAC9F,WAAO,QAAQ;AAAA,EACjB;AAEA,SAAO,GAAG,SAAS,IAAI,GAAG,EAAE,QAAQ,qCAAqC,gBAAgB;AAC3F;AAEO,IAAM,oBAAoB,CAAC,YAA4B;AAC5D,MAAI,KAAK,QAAQ,YAAY;AAC7B,MAAI,GAAG,WAAW,IAAI,GAAG;AACvB,SAAK,GAAG,MAAM,CAAC;AAAA,EACjB;AACA,MAAI,GAAG,WAAW,IAAI;AACpB,YAAQ,KAAK,YAAY,OAAO,wEAAwE;AAAA,EAC1G;AACA,MAAI,CAAC,cAAc,KAAK,EAAE,GAAG;AAC3B,YAAQ,MAAM,YAAY,OAAO,+DAA+D;AAChG,WAAO,QAAQ;AAAA,EACjB;AAEA,SAAO,GAAG,QAAQ,qCAAqC,gBAAgB;AACzE;AAEO,IAAM,oBAAoB,CAAC,SAAyB;AACzD,SAAO,KAAK,QAAQ,MAAM,EAAE;AAC9B;;;AD5CA,4BAAkC;AAU3B,SAAS,WAId;AAAA,EACE;AAAA,EACA;AAAA,EACA;AAAA,EACA,iBAAiB;AAAA,EACjB;AACF,GACA,IACA,YACG,MACH;AACA,MAAI,gBAAgB,oBAAQ,OAAO;AAEnC,QAAM,+BAA+B,cAAc,SAAS,0BAA0B;AAEtF,MAAI,uBAAuB;AACzB,oBAAgB,cAAc;AAAA,MAC5B;AAAA,MACA,EAAE,GAAI,sEAAgC,CAAC,GAAI,GAAG,sBAAsB;AAAA,IACtE;AAAA,EACF;AAEA,QAAM,kBAAkB,YAAY,aAAa;AACjD,QAAM,WAAW,kBAAkB,GAAG,eAAe,IAAI,IAAI,KAAK;AAClE,kBAAgB,cAAc,SAAS,eAAe,QAAQ;AAC9D,MAAI,SAAS;AACX,QAAI,aAAa,OAAO,GAAG;AACzB,YAAM,cAAc;AAAA,QAClB,SAAS,kBAAkB,OAAO;AAAA,QAClC,QAAQ,IAAI,wCAAkB,EAAE,eAAe;AAAA,QAC/C,YAAY,uBAAW;AAAA,QACvB,UAAU;AAAA,MACZ;AACA,sBAAgB,kBAAM,eAAe,eAAe,WAAW;AAAA,IACjE,OAAO;AACL,cAAQ,KAAK,oBAAoB,OAAO,oBAAoB;AAAA,IAC9D;AAAA,EACF;AAEA,MAAI,uBAAuB;AACzB,wBAAgB,8BAAgB,aAAa;AAAA,EAC/C;AAEA,SAAO,oBAAQ;AAAA,IAAK;AAAA,IAAe,MACjC,UAAU,EAAE;AAAA,MACV;AAAA,MACA,CAAC;AAAA,MACD;AAAA,MACA,OAAO,SAAe;AACpB,YAAI,WAAW,aAAa,OAAO,GAAG;AACpC,eAAK,aAAa,sBAAsB,IAAI;AAAA,QAC9C;AAEA,YAAI,iBAAiB,GAAG;AACtB,cAAI;AACF,kBAAM,QAAQ,4CAAmB;AACjC,gBACE,MAAM,WAAW,KACjB,OAAO,MAAM,CAAC,MAAM,YACpB,EAAE,MAAM,CAAC,aAAa,MACtB;AACA,mBAAK;AAAA,gBACH;AAAA,gBACA,UAAU,MAAM,CAAC,CAAC;AAAA,cACpB;AAAA,YACF,OAAO;AAGL,mBAAK;AAAA,gBACH;AAAA,gBACA,UAAU,MAAM,SAAS,IAAI,QAAQ,CAAC,CAAC;AAAA,cACzC;AAAA,YACF;AAAA,UACF,SAAS,OAAO;AACd,oBAAQ,KAAK,6BAA6B,KAAK;AAAA,UACjD;AAAA,QACF;AAGA,cAAM,EAAE,aAAa,UAAU,GAAG,KAAK,IAAI,wDAAyB,CAAC;AACrE,wBAAgB,cAAc;AAAA,UAC5B;AAAA,UACA,EAAE,GAAI,sEAAgC,CAAC,GAAI,GAAG,KAAK;AAAA,QACrD;AAEA,cAAM,MAAM,GAAG,MAAM,SAAS,IAAI;AAElC,YAAI,eAAe,SAAS;AAC1B,iBAAO,IAAI,KAAK,CAAC,gBAAgB;AAC/B,gBAAI;AACF,kBAAI,iBAAiB,GAAG;AACtB,qBAAK;AAAA,kBACH;AAAA,kBACA,UAAU,WAAW;AAAA,gBACvB;AAAA,cACF;AAAA,YACF,SAAS,OAAO;AACd,sBAAQ,KAAK,oCAAoC,KAAK;AAAA,YACxD,UAAE;AACA,mBAAK,IAAI;AAAA,YACX;AAEA,mBAAO;AAAA,UACT,CAAC;AAAA,QACH;AACA,YAAI;AACF,cAAI,iBAAiB,GAAG;AACtB,iBAAK;AAAA,cACH;AAAA,cACA,UAAU,GAAG;AAAA,YACf;AAAA,UACF;AAAA,QACF,SAAS,OAAO;AACd,kBAAQ,KAAK,8BAA8B,KAAK;AAAA,QAClD,UAAE;AACA,eAAK,IAAI;AAAA,QACX;AAEA,eAAO;AAAA,MACT;AAAA,IACF;AAAA,EACF;AACF;AAEA,SAAS,WAAW,OAAyB;AAC3C,MAAI,iBAAiB,KAAK;AACxB,WAAO,MAAM,KAAK,MAAM,QAAQ,CAAC;AAAA,EACnC,WAAW,MAAM,QAAQ,KAAK,GAAG;AAC/B,WAAO,MAAM,IAAI,CAAC,UAAU,WAAW,KAAK,CAAC;AAAA,EAC/C,WAAW,CAAC,OAAO;AACjB,WAAO;AAAA,EACT,WAAW,OAAO,UAAU,UAAU;AAEpC,UAAM,SAAc,CAAC;AACrB,WAAO,QAAQ,KAAY,EAAE,QAAQ,CAAC,CAAC,KAAK,KAAK,MAAM;AACrD,aAAO,GAAG,IAAI,WAAW,KAAK;AAAA,IAChC,CAAC;AACD,WAAO;AAAA,EACT;AAEA,SAAO;AACT;AAEA,SAAS,UAAU,OAAwB;AACzC,SAAO,KAAK,UAAU,WAAW,KAAK,CAAC;AACzC;;;ANtJA,sCAAkC;AAClC,qBAAyB;AAczB,IAAAC,yBAAkC;AAY3B,IAAM,UAAN,MAAc;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EA4CnB,OAAc,WAAW;AAAA,IACvB;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,EACF,GAA2B;AAEzB,QAAI,MAAM,wCAAiB,QAAQ,IAAI;AACvC,QAAI,QAAQ,QAAW;AACrB,YAAM,IAAI;AAAA,QACR;AAAA,MAEF;AAAA,IACF;AACA,SAAK,gBAAgB;AACrB,QAAI,mCAAS,MAAM,eAAe;AAChC,YAAM,IAAI;AAAA,QACR;AAAA,MACF;AAAA,IACF;AAEA,SAAK,cAAc,GAAG,4BAAW,qBAAqB,IAAI,8BAAY,GAAG;AACzE,SAAK,cAAc,GAAG,4BAAW,qBAAqB,IAAI,8BAAY,IAAI;AAE1E,SAAK,gBAAgB;AACrB,SAAK,MAAM,oBAAO,CAAC;AAEnB,UAAM,WAAW,IAAI,wBAAS;AAC9B,aAAS,IAAI,iBAAiB,UAAU,KAAK,aAAa,EAAE;AAC5D,UAAM,WAAW,IAAI,kDAAkB;AAAA,MACrC,KAAK,KAAK;AAAA,MACV;AAAA,IACF,CAAC;AAED,eAAoB;AAAA,MAClB;AAAA,MACA,8BAA8B;AAAA,MAC9B;AAAA,MACA,cAAc;AAAA,IAChB,CAAC;AAAA,EACH;AAAA;AAAA;AAAA;AAAA;AAAA,EAMA,OAAc,cAAuB;AACnC,WAAO,KAAK;AAAA,EACd;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAQA,OAAc,OAAO,KAA8B;AACjD,QAAI,KAAK;AACP,WAAK,MAAM;AAAA,IACb;AAAA,EACF;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAQA,OAAc,iBAAiB,eAAwB;AACrD,QAAI,eAAe;AACjB,WAAK,gBAAgB;AAAA,IACvB;AAAA,EACF;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAgBA,aAAoB,IAAI;AAAA,IACtB;AAAA,IACA;AAAA,IACA;AAAA,IACA,WAAW,CAAC;AAAA,IACZ;AAAA,IACA;AAAA,EACF,GAAqD;AACnD,UAAM,cAAc,kBAAM,cAAc;AACxC,QAAI;AACJ,QAAI;AACJ,QAAI,gBAAgB,cAAa,gCAAmB,YAAY,YAAY,CAAC,GAAG;AAC9E,qBAAe,wCAAiB,iBAAiB,YAAY,YAAY,EAAE,MAAM;AACjF,gBAAU,0CAAkB,kBAAkB,YAAY,YAAY,EAAE,OAAO;AAAA,IACjF,OAAO;AACL,qBAAe;AACf,gBAAU;AAAA,IACZ;AACA,QAAI,KAAK,kBAAkB,QAAW;AACpC,YAAM,IAAI;AAAA,QACR;AAAA,MAEF;AAAA,IACF;AACA,UAAM,eAAe,QAAQ,SAAY,KAAK,MAAM;AAEpD,UAAM,WAAW,MAAM,MAAM,GAAG,KAAK,WAAW,oBAAoB;AAAA,MAClE,QAAQ;AAAA,MACR,SAAS,KAAK,WAAW;AAAA,MACzB,MAAM,KAAK,UAAU;AAAA,QACnB;AAAA,QACA;AAAA,QACA,KAAK;AAAA,QACL;AAAA,QACA;AAAA,QACA;AAAA,MACF,CAAC;AAAA,IACH,CAAC;AAED,QAAI,CAAC,SAAS,IAAI;AAChB,YAAM,IAAI,MAAM,0BAA0B,QAAQ,eAAe,SAAS,UAAU,EAAE;AAAA,IACxF;AACA,QAAI;AACF,aAAO,MAAM,SAAS,KAAK;AAAA,IAC7B,SAAS,OAAO;AACd,YAAM,IAAI,MAAM,0CAA0C,QAAQ,YAAY,KAAK,EAAE;AAAA,IACvF;AAAA,EACF;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAiBA,OAAc,MACZ,MACA,OACA,WACA;AACA,UAAM,cAAc,kBAAM,cAAc;AACxC,QAAI,gBAAgB,UAAa,KAAC,gCAAmB,YAAY,YAAY,CAAC,GAAG;AAC/E,cAAQ;AAAA,QAAK,8DACA,IAAI;AAAA,MAEjB;AACA;AAAA,IACF;AAEA,UAAM,QAAoB;AAAA,MACxB,mBAAmB;AAAA,IACrB;AACA,QAAI,UAAU,QAAW;AACvB,YAAM,kBAAkB,IAAI;AAAA,IAC9B;AAEA,gBAAY,SAAS,MAAM,OAAO,SAAS;AAAA,EAC7C;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAmBA,OAAc,mBAAmB;AAAA,IAC/B;AAAA,IACA;AAAA,EACF,GAAqD;AACnD,YAAQ,KAAK,0EAA0E;AACvF,UAAM,cAAc,kBAAM,cAAc;AACxC,QAAI,gBAAgB,cAAa,gCAAmB,YAAY,YAAY,CAAC,GAAG;AAC9E,UAAI,WAAW;AACb,oBAAY,aAAa,YAAY,KAAK,UAAU,SAAS,CAAC;AAAA,MAChE;AACA,UAAI,QAAQ;AACV,oBAAY,aAAa,SAAS,KAAK,UAAU,MAAM,CAAC;AAAA,MAC1D;AAAA,IACF;AACA,QAAI,wBAAwB,CAAC;AAC7B,QAAI,WAAW;AACb,8BAAwB,EAAE,GAAG,uBAAuB,cAAc,KAAK,UAAU,SAAS,EAAE;AAAA,IAC9F;AACA,QAAI,QAAQ;AACV,8BAAwB,EAAE,GAAG,uBAAuB,WAAW,KAAK,UAAU,MAAM,EAAE;AAAA,IACxF;AAEA,QAAI,gBAAgB,YAAAC,QAAW,OAAO;AACtC,UAAM,+BAA+B,cAAc,SAAS,0BAA0B;AACtF,QAAI,uBAAuB;AACzB,sBAAgB,cAAc;AAAA,QAC5B;AAAA,QACA,EAAE,GAAI,sEAAgC,CAAC,GAAI,GAAG,sBAAsB;AAAA,MACtE;AAAA,IACF;AAEA,WAAO;AAAA,EACT;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAiBA,OAAc,YACZ,WACA,IACA;AACA,UAAM,cAAc,kBAAM,cAAc;AACxC,QAAI,gBAAgB,cAAa,gCAAmB,YAAY,YAAY,CAAC,GAAG;AAC9E,UAAI,WAAW;AACb,oBAAY,aAAa,YAAY,KAAK,UAAU,SAAS,CAAC;AAAA,MAChE;AAAA,IACF;AACA,QAAI,wBAAwB,CAAC;AAC7B,QAAI,WAAW;AACb,8BAAwB,EAAE,GAAG,uBAAuB,cAAc,KAAK,UAAU,SAAS,EAAE;AAAA,IAC9F;AAEA,QAAI,gBAAgB,YAAAA,QAAW,OAAO;AACtC,UAAM,+BAA+B,cAAc,SAAS,0BAA0B;AACtF,QAAI,yBAAyB,OAAO,KAAK,qBAAqB,EAAE,SAAS,GAAG;AAC1E,sBAAgB,cAAc;AAAA,QAC5B;AAAA,QACA,EAAE,GAAI,sEAAgC,CAAC,GAAI,GAAG,sBAAsB;AAAA,MACtE;AAAA,IACF;AACA,WAAO,YAAAA,QAAW,KAAK,eAAe,EAAE;AAAA,EAC1C;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAuBA,OAAc,aACZ,UACA,IACA;AACA,UAAM,cAAc,kBAAM,cAAc;AACxC,QAAI,gBAAgB,cAAa,gCAAmB,YAAY,YAAY,CAAC,GAAG;AAC9E,iBAAW,CAAC,KAAK,KAAK,KAAK,OAAO,QAAQ,QAAQ,GAAG;AACnD,oBAAY,aAAa,GAAG,sBAAsB,aAAa,GAAG,IAAI,KAAK,UAAU,KAAK,CAAC;AAAA,MAC7F;AAAA,IACF;AACA,QAAI,qBAAqB,CAAC;AAC1B,eAAW,CAAC,KAAK,KAAK,KAAK,OAAO,QAAQ,QAAQ,GAAG;AACnD,2BAAqB,EAAE,GAAG,oBAAoB,CAAC,YAAY,GAAG,EAAE,GAAG,KAAK,UAAU,KAAK,EAAE;AAAA,IAC3F;AAEA,QAAI,gBAAgB,YAAAA,QAAW,OAAO;AACtC,UAAM,+BAA+B,cAAc,SAAS,0BAA0B;AACtF,QAAI,sBAAsB,OAAO,KAAK,kBAAkB,EAAE,SAAS,GAAG;AACpE,sBAAgB,cAAc;AAAA,QAC5B;AAAA,QACA,EAAE,GAAI,sEAAgC,CAAC,GAAI,GAAG,mBAAmB;AAAA,MACnE;AAAA,IACF;AACA,WAAO,YAAAA,QAAW,KAAK,eAAe,EAAE;AAAA,EAC1C;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAoBA,OAAc,kBACZ,YACA;AACA,UAAM,cAAc,kBAAM,cAAc;AACxC,QAAI,gBAAgB,cAAa,gCAAmB,YAAY,YAAY,CAAC,GAAG;AAC9E,iBAAW,CAAC,KAAK,KAAK,KAAK,OAAO,QAAQ,UAAU,GAAG;AACrD,oBAAY,aAAa,KAAK,KAAK,UAAU,KAAK,CAAC;AAAA,MACrD;AAAA,IACF;AAAA,EACF;AAAA;AAAA;AAAA;AAAA;AAAA,EAMA,OAAc,cAAc,QAAa;AACvC,QAAI,UAAU,MAAM;AAClB;AAAA,IACF;AACA,UAAM,cAAc,kBAAM,cAAc;AACxC,QAAI,gBAAgB,cAAa,gCAAmB,YAAY,YAAY,CAAC,GAAG;AAC9E,kBAAY,aAAa,aAAa,KAAK,UAAU,MAAM,CAAC;AAAA,IAC9D;AAAA,EACF;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EA4CA,OAAc,UAAU;AAAA,IACtB;AAAA,IACA;AAAA,IACA;AAAA,IACA,SAAAC;AAAA,IACA;AAAA,IACA;AAAA,EACF,GAOS;AACP,QAAI,gBAAgBA,YAAA,OAAAA,WAAW,YAAAD,QAAW,OAAO;AACjD,UAAM,kBAAkB,YAAY,aAAa;AACjD,UAAM,WAAW,kBAAkB,GAAG,eAAe,IAAI,IAAI,KAAK;AAClE,oBAAgB,cAAc,SAAS,eAAe,QAAQ;AAC9D,QAAI,SAAS;AACX,UAAI,aAAa,OAAO,GAAG;AACzB,cAAM,cAAc;AAAA,UAClB,SAAS,kBAAkB,OAAO;AAAA,UAClC,QAAQ,IAAI,yCAAkB,EAAE,eAAe;AAAA,UAC/C,YAAY,uBAAW;AAAA,UACvB,UAAU;AAAA,QACZ;AACA,wBAAgB,kBAAM,eAAe,eAAe,WAAW;AAAA,MACjE,OAAO;AACL,gBAAQ,KAAK,oBAAoB,OAAO,oBAAoB;AAAA,MAC9D;AAAA,IACF;AACA,UAAM,kBAAkB,SAAS,OAAO,QAAQ,MAAM,EAAE,OAAO,CAAC,KAAK,CAAC,KAAK,KAAK,MAAM;AACpF,UAAI,GAAG,sBAAsB,UAAU,GAAG,EAAE,IAAI;AAChD,aAAO;AAAA,IACT,GAAG,CAAC,CAA2B,IAAI,CAAC;AACpC,UAAM,aAAa;AAAA,MACjB,CAAC,SAAS,GAAG,8BAAY;AAAA,MACzB,CAAC,SAAS,GAAG;AAAA,MACb,GAAG;AAAA,IACL;AACA,UAAM,OAAO,UAAU,EAAE,UAAU,MAAM,EAAE,WAAW,GAAG,aAAa;AACtE,QAAI,SAAS;AACX,WAAK,aAAa,sBAAsB,IAAI;AAAA,IAC9C;AACA,QAAI,OAAO;AACT,WAAK,aAAa,YAAY,KAAK,UAAU,KAAK,CAAC;AAAA,IACrD;AACA,WAAO;AAAA,EACT;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAeA,OAAc,SAAY,MAAY,IAAa,WAAwB;AACzE,WAAO,YAAAA,QAAW,KAAK,kBAAM,QAAQ,YAAAA,QAAW,OAAO,GAAG,IAAI,GAAG,MAAM;AACrE,UAAG;AACD,cAAM,SAAS,GAAG;AAClB,eAAO;AAAA,MACT,UACA;AACE,YAAI,cAAc,UAAa,WAAW;AACxC,eAAK,IAAI;AAAA,QACX;AAAA,MACF;AAAA,IACF,CAAC;AAAA,EACH;AAAA,EAEA,aAAoB,WAAW;AAC7B,UAAM,WAAW;AAAA,EACnB;AAAA,EAEA,aAAoB,iBAA0B;AAAA,IAC5C;AAAA,IACA;AAAA,IACA;AAAA,EACF,GAIsC;AACpC,QAAI,OAAO;AACX,QAAI;AACF,aAAO,KAAK,UAAU;AAAA,QACpB,SAAS,4BAAW;AAAA,QACpB,MAAM,sBAAQ;AAAA,QACd,QAAQ;AAAA,MACV,CAAC;AAAA,IACH,SAAS,OAAO;AACd,YAAM,IAAI,MAAM,2CAA2C,IAAI,YAAY,KAAK,EAAE;AAAA,IACpF;AACA,UAAM,WAAW,MAAM,MAAM,GAAG,KAAK,WAAW,mBAAmB;AAAA,MACjE,QAAQ;AAAA,MACR,SAAS,KAAK,WAAW;AAAA,MACzB;AAAA,IACF,CAAC;AAED,QAAI,CAAC,SAAS,IAAI;AAChB,YAAM,IAAI,MAAM,+BAA+B,IAAI,eAAe,SAAS,UAAU,EAAE;AAAA,IACzF;AAEA,WAAO,MAAM,SAAS,KAAK;AAAA,EAC7B;AAAA,EAEA,aAAoB,cAAoB;AAAA,IACtC;AAAA,IACA;AAAA,IACA;AAAA,EACF,GAIyC;AACvC,UAAM,SAAS,IAAI,gBAAgB;AAAA,MACjC,MAAM;AAAA,MACN,QAAQ,OAAO,SAAS;AAAA,MACxB,OAAO,MAAM,SAAS;AAAA,IACxB,CAAC;AACD,UAAM,WAAW,MAAM,MAAM,GAAG,KAAK,WAAW,2BAA2B,OAAO,SAAS,CAAC,IAAI;AAAA,MAC9F,QAAQ;AAAA,MACR,SAAS,KAAK,WAAW;AAAA,IAC3B,CAAC;AAED,QAAI,CAAC,SAAS,IAAI;AAChB,YAAM,IAAI,MAAM,wCAAwC,WAAW,eAAe,SAAS,UAAU,EAAE;AAAA,IACzG;AAEA,WAAO,MAAM,SAAS,KAAK;AAAA,EAC7B;AAAA,EAEA,OAAe,aAAa;AAC1B,WAAO;AAAA,MACL,gBAAgB;AAAA,MAChB,iBAAiB,UAAU,KAAK,aAAa;AAAA,IAC/C;AAAA,EACF;AACF;AAhlBa,QAII,MAA8B,CAAC;AAJnC,QAKI,gBAAyB;;;AQlD1C,0BAAwB;;;ACCxB,IAAM,qBAAqB;AAEpB,IAAe,oBAAf,MAAuC;AAAA,EAC5C,MAAa,MAAM,OAAe,KAAyC;AACzE,UAAM,SAAS,CAAC;AAChB,aAAS,IAAI,KAAK,IAAI,OAAO,CAAC,GAAG,IAAI,KAAK,IAAI,KAAK,MAAM,KAAK,KAAK,CAAC,GAAG,KAAK;AAC1E,aAAO,KAAK,MAAM,KAAK,IAAI,CAAC,CAAC;AAAA,IAC/B;AACA,WAAO;AAAA,EACT;AAGF;AAEO,IAAM,iBAAN,cAAmC,kBAAwB;AAAA,EAOhE,YAAY,MAAc,WAAoB;AAC5C,UAAM;AAPR,SAAQ,eAAkC,CAAC;AAC3C,SAAQ,MAAqB;AAC7B,SAAQ,SAAiB;AAMvB,SAAK,OAAO;AACZ,SAAK,YAAY,aAAa;AAAA,EAChC;AAAA,EAEA,MAAc,aAAa;AAGzB,UAAM,OAAO,MAAM,QAAE,cAAoB;AAAA,MACvC,aAAa,KAAK;AAAA,MAClB,QAAQ,KAAK;AAAA,MACb,OAAO,KAAK;AAAA,IACd,CAAC;AACD,SAAK,eAAe,KAAK,aAAa,OAAO,KAAK,KAAK;AACvD,SAAK,SAAS,KAAK,aAAa;AAChC,QAAI,KAAK,QAAQ,MAAM;AACrB,WAAK,MAAM,KAAK;AAAA,IAClB;AAAA,EACF;AAAA,EAEA,MAAa,OAAwB;AACnC,QAAI,KAAK,QAAQ,MAAM;AACrB,YAAM,KAAK,WAAW;AAAA,IACxB;AACA,WAAO,KAAK;AAAA,EACd;AAAA,EACA,MAAa,IAAI,OAAyC;AACxD,QAAI,SAAS,KAAK,aAAa,QAAQ;AACrC,YAAM,KAAK,WAAW;AAAA,IACxB;AACA,WAAO,KAAK,aAAa,KAAK;AAAA,EAChC;AACF;;;ACzDA,IAAAE,cAAiD;AAqCjD,eAAsB,QACpB;AAAA,EACE;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACF,GAAmB,OAAU,MAAiC;AAC9D,MAAI,OAAO,UAAa,OAAO,OAAO,YAAY;AAChD,UAAM,IAAI,MAAM,mEAAmE;AAAA,EACrF;AAEA,MAAI,wBAAwB,CAAC;AAC7B,MAAI,WAAW;AACb,4BAAwB,EAAE,GAAG,uBAAuB,cAAc,UAAU;AAAA,EAC9E;AACA,MAAI,QAAQ;AACV,4BAAwB,EAAE,GAAG,uBAAuB,WAAW,OAAO;AAAA,EACxE;AACA,MAAI,WAAW;AACb,4BAAwB,EAAE,GAAG,uBAAuB,cAAc,UAAU;AAAA,EAC9E;AACA,MAAI,UAAU;AACZ,4BAAwB,EAAE,GAAG,uBAAuB,aAAa,SAAS;AAAA,EAC5E;AAEA,SAAO,MAAM,WAAiB;AAAA,IAC5B,MAAM,sBAAQ,GAAG;AAAA,IACjB;AAAA,IACA;AAAA,EACF,GAAG,IAAI,QAAW,GAAG,IAAI;AAC3B;AAwBO,SAAS,WACd,QACA,OACG,MACY;AAjGjB;AAkGE,MAAI,gBAAgB,oBAAQ,OAAO;AACnC,QAAM,gCAA+B,mBAAc,SAAS,0BAA0B,MAAjD,YAAsD,CAAC;AAC5F,QAAM,kBAAkB,OAAO,QAAQ,MAAM,EAAE,OAAO,CAAC,KAAK,CAAC,KAAK,KAAK,MAAM;AAC3E,QAAI,SAAS,GAAG,EAAE,IAAI;AACtB,WAAO;AAAA,EACT,GAAG,CAAC,CAA2B;AAE/B,kBAAgB,cAAc;AAAA,IAC5B;AAAA,IACA,EAAE,GAAG,8BAA8B,GAAG,gBAAgB;AAAA,EACxD;AAEA,QAAM,SAAS,oBAAQ,KAAK,eAAe,MAAM;AAC/C,WAAO,GAAG,MAAM,QAAW,IAAI;AAAA,EACjC,CAAC;AAED,QAAM,4BAA4B,mBAAc,SAAS,0BAA0B,MAAjD,YAAsD,CAAC;AACzF,aAAW,CAAC,KAAK,KAAK,KAAK,OAAO,QAAQ,eAAe,GAAG;AAC1D,WAAO,yBAAyB,SAAS,GAAG,EAAE;AAAA,EAChD;AAEA,kBAAgB,cAAc;AAAA,IAC5B;AAAA,IACA;AAAA,EACF;AAEA,SAAO;AACT;;;AFvHA,IAAAC,cAAsB;AAItB,IAAM,qBAAqB;AAQ3B,IAAM,mBAAmB,CAAC,WAAmB,iBAAyB;AACpE,SAAO,+BAA+B,SAAS,gBAAgB,YAAY;AAC7E;AAEA,IAAM,mBACJ,CAAU,YAAoE;AAC5E,QAAM,iBAA2C,CAAC;AAClD,aAAW,UAAU,SAAS;AAC5B,eAAW,OAAO,OAAO,QAAQ;AAC/B,UAAI,eAAe,GAAG,GAAG;AACvB,uBAAe,GAAG,EAAE,KAAK,OAAO,OAAO,GAAG,CAAC;AAAA,MAC7C,OAAO;AACL,uBAAe,GAAG,IAAI,CAAC,OAAO,OAAO,GAAG,CAAC;AAAA,MAC3C;AAAA,IACF;AAAA,EACF;AAEA,QAAM,gBAAwC,CAAC;AAC/C,aAAW,OAAO,gBAAgB;AAChC,kBAAc,GAAG,IAAI,eAAe,GAAG,EAAE,OAAO,CAAC,GAAG,MAAM,IAAI,GAAG,CAAC,IAC9D,eAAe,GAAG,EAAE;AAAA,EAC1B;AAEA,SAAO;AACT;AAqEK,IAAM,iBAAN,MAAqB;AAAA,EAG1B,YAAY,WAAmB;AAC7B,SAAK,YAAY;AAAA,EACnB;AACF;AA6CA,IAAM,qBAAN,MAAyB;AAAA,EAOvB,cAAc;AANd,SAAQ,cAAqC,IAAI,oBAAAC,QAAY;AAAA,MAC3D,CAAC;AAAA,MACD,oBAAAA,QAAY,QAAQ;AAAA,IACtB;AACA,SAAQ,kBAA0B;AAAA,EAElB;AAAA,EAET,MAAM,EAAE,OAAO,GAAuB;AAC3C,SAAK,YAAY,MAAM,QAAQ,CAAC;AAAA,EAClC;AAAA,EAEO,OAAO,aAAqB;AACjC,SAAK,mBAAmB;AACxB,SAAK,YAAY,OAAO,KAAK,eAAe;AAAA,EAC9C;AAAA;AAAA,EAGO,cAAc,OAAc;AACjC,SAAK,YAAY,KAAK;AACtB,YAAQ,OAAO,MAAM;AAAA,SAAY,MAAM,OAAO;AAAA,CAAI;AAAA,EACpD;AAAA;AAAA,EAGO,KAAK;AAAA,IACV;AAAA,IACA;AAAA,IACA;AAAA,EACF,GAAuF;AACrF,SAAK,YAAY,KAAK;AACtB,YAAQ,OAAO,MAAM;AAAA,mBAAsB,iBAAiB,WAAW,YAAY,CAAC;AAAA,CAAI;AACxF,YAAQ,OAAO,MAAM,qBAAqB;AAC1C,eAAW,OAAO,eAAe;AAC/B,cAAQ,OAAO,MAAM,GAAG,GAAG,KAAK,KAAK,UAAU,cAAc,GAAG,CAAC,CAAC;AAAA,CAAI;AAAA,IACxE;AACA,YAAQ,OAAO,MAAM,IAAI;AAAA,EAC3B;AACF;AAEA,IAAM,aAAN,MAA0B;AAAA,EAWxB,YAAY;AAAA,IACV;AAAA,IAAM;AAAA,IAAU;AAAA,IAAY;AAAA,IAAiB;AAAA,IAAS;AAAA,IAAM;AAAA,EAC9D,GAAwC;AAZxC,SAAQ,aAAsB;AAQ9B,SAAQ,YAAoB;AAnN9B;AAwNI,QAAI,OAAO,KAAK,UAAU,EAAE,WAAW,GAAG;AACxC,YAAM,IAAI,MAAM,wBAAwB;AAAA,IAC1C;AAEA,UAAM,qBAAqB;AAE3B,eAAW,OAAO,YAAY;AAC5B,UAAI,CAAC,mBAAmB,KAAK,GAAG,GAAG;AACjC,cAAM,IAAI;AAAA,UACR,2BAA2B,GAAG;AAAA,QAEhC;AAAA,MACF;AAAA,IACF;AAEA,SAAK,mBAAmB,IAAI,mBAAmB;AAC/C,SAAK,OAAO;AACZ,SAAK,WAAW;AAChB,SAAK,aAAa;AAClB,SAAK,kBAAkB;AACvB,SAAK,UAAU;AACf,SAAK,OAAO;AACZ,QAAI,QAAQ;AACV,WAAK,aAAY,YAAO,cAAP,YAAoB;AAAA,IACvC;AACA,YAAQ,WAAW;AAAA,MACjB,eAAe,iCAAQ;AAAA,MACvB,SAAS,iCAAQ;AAAA,MACjB,UAAU,iCAAQ;AAAA,MAClB,UAAU,iCAAQ;AAAA,MAClB,mBAAmB,iCAAQ;AAAA,IAC7B,CAAC;AAAA,EACH;AAAA,EAEA,MAAa,MAAqB;AAChC,QAAI,KAAK,YAAY;AACnB,YAAM,IAAI,MAAM,gCAAgC;AAAA,IAClD;AAEA,SAAK,iBAAiB,MAAM,EAAE,QAAQ,MAAM,KAAK,UAAU,EAAE,CAAC;AAC9D,QAAI;AACJ,QAAI;AACF,yBAAmB,MAAM,KAAK,kBAAkB;AAAA,IAClD,SAAS,GAAG;AACV,WAAK,iBAAiB,cAAc,CAAU;AAC9C,WAAK,aAAa;AAClB;AAAA,IACF;AAEA,UAAM,aAAa,MAAM,QAAQ,iBAAiB;AAAA,MAChD,SAAS,KAAK;AAAA,MACd,MAAM,KAAK;AAAA,MACX,MAAM;AAAA,IACR,CAAC;AACD,UAAM,gBAAgB,iBAAiB,gBAAgB;AACvD,SAAK,iBAAiB,KAAK;AAAA,MACzB;AAAA,MACA,WAAW,WAAW;AAAA,MACtB,cAAc,WAAW;AAAA,IAC3B,CAAC;AACD,SAAK,aAAa;AAElB,UAAM,QAAQ,SAAS;AAAA,EACzB;AAAA,EAEA,MAAa,oBAA6D;AACxE,UAAM,mBAAmD,CAAC;AAC1D,aAAS,IAAI,GAAG,IAAI,MAAM,KAAK,UAAU,GAAG,KAAK,KAAK,WAAW;AAC/D,YAAM,QAAQ,MAAM,KAAK,KAAK,MAAM,GAAG,IAAI,KAAK,SAAS;AACzD,YAAM,kBAAkB,MAAM,KAAK,cAAc,KAAK;AACtD,uBAAiB,KAAK,GAAG,eAAe;AACxC,WAAK,iBAAiB,OAAO,MAAM,MAAM;AAAA,IAC3C;AACA,WAAO;AAAA,EACT;AAAA,EAEA,MAAc,cAAc,OAAmE;AAC7F,UAAM,gBAAgB,MAAM,IAAI,OAAO,cAAc;AACnD,UAAI;AAIJ,YAAM,QAAQ,EAAE,MAAM,cAAc,WAAW,aAAa,GAAG,YAAY;AACzE,0BAAM,cAAc,EAAG,aAAa,WAAW,YAAY;AAE3D,cAAM,EAAE,QAAQ,eAAe,IAAI,MAAM;AAAA,UACvC,EAAE,MAAM,WAAW;AAAA,UACnB,OAAO,SAAY;AACjB,kBAAMC,kBAAiB,kBAAM,cAAc,EAAG,YAAY,EAAE;AAC5D,8BAAM,cAAc,EAAG,aAAa,WAAW,UAAU;AACzD,mBAAO;AAAA,cACL,QAAQ,MAAM,KAAK,SAAS,IAAI;AAAA,cAChC,gBAAgB,iBAAiBA,eAAc;AAAA,YACjD;AAAA,UACF;AAAA,UACA,UAAU;AAAA,QACZ;AACA,cAAM,SAAS,UAAU;AAEzB,YAAI,SAAiC,CAAC;AACtC,mBAAW,CAAC,eAAe,SAAS,KAAK,OAAO,QAAQ,KAAK,UAAU,GAAG;AACxE,gBAAM,QAAQ,MAAM;AAAA,YAClB,EAAE,MAAM,cAAc;AAAA,YACtB,OAAOC,SAAWC,YAAe;AAC/B,gCAAM,cAAc,EAAG,aAAa,WAAW,WAAW;AAC1D,qBAAO,MAAM,UAAUD,SAAQC,OAAM;AAAA,YACvC;AAAA,YACA;AAAA,YACA;AAAA,UACF;AAEA,cAAI,OAAO,UAAU,UAAU;AAC7B,gBAAI,MAAM,KAAK,GAAG;AAChB,oBAAM,IAAI,MAAM,aAAa,aAAa,eAAe;AAAA,YAC3D;AACA,mBAAO,aAAa,IAAI;AAAA,UAC1B,OAAO;AACL,qBAAS,EAAE,GAAG,QAAQ,GAAG,MAAM;AAAA,UACjC;AAAA,QACF;AAEA,cAAM;AAAA,UACJ,gBAAgB;AAAA,UAChB,MAAM,UAAU;AAAA,UAChB;AAAA,UACA;AAAA,UACA,SAAS,kBAAkB,kBAAM,cAAc,EAAG,YAAY,EAAE,OAAO;AAAA;AAAA;AAAA;AAAA,UAIvE,iBAAiB,KAAK;AAAA,UACtB;AAAA,QACF;AAAA,MACF,CAAC;AAED,aAAO;AAAA,IACT,CAAC;AAED,UAAM,UAAU,MAAM,QAAQ,IAAI,aAAa;AAE/C,WAAO;AAAA,EACT;AAAA,EAEA,MAAc,YAA6B;AACzC,WAAO,KAAK,gBAAgB,oBAAoB,MAAM,KAAK,KAAK,KAAK,IAAI,KAAK,KAAK;AAAA,EACrF;AACF;AAuBA,eAAsB,SAAkB;AAAA,EACtC;AAAA,EAAM;AAAA,EAAU;AAAA,EAAY;AAAA,EAAiB;AAAA,EAAS;AAAA,EAAM;AAC9D,GAAuD;AACrD,QAAM,aAAa,IAAI,WAAW;AAAA,IAChC;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,EACF,CAAC;AACD,MAAI,WAAW,wBAAwB;AACrC,eAAW,cAAc;AAAA,EAC3B,OAAO;AACL,UAAM,WAAW,IAAI;AAAA,EACvB;AACF;;;ATpYA,IAAAC,cAAqB;","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
@@ -708,6 +708,7 @@ var Laminar = class {
708
708
  currentSpan.addEvent(name, event, timestamp);
709
709
  }
710
710
  /**
711
+ * DEPRECATED: use `withSession` and/or `withMetadata` instead.
711
712
  * Sets the session information for the current span and returns the
712
713
  * context to use for the following spans.
713
714
  *
@@ -727,21 +728,22 @@ var Laminar = class {
727
728
  sessionId,
728
729
  userId
729
730
  }) {
731
+ console.warn("Laminar().contextWithSession() is deprecated. Use withSession() instead.");
730
732
  const currentSpan = trace3.getActiveSpan();
731
733
  if (currentSpan !== void 0 && isSpanContextValid(currentSpan.spanContext())) {
732
734
  if (sessionId) {
733
- currentSpan.setAttribute(SESSION_ID, sessionId);
735
+ currentSpan.setAttribute(SESSION_ID, JSON.stringify(sessionId));
734
736
  }
735
737
  if (userId) {
736
- currentSpan.setAttribute(USER_ID, userId);
738
+ currentSpan.setAttribute(USER_ID, JSON.stringify(userId));
737
739
  }
738
740
  }
739
741
  let associationProperties = {};
740
742
  if (sessionId) {
741
- associationProperties = { ...associationProperties, "session_id": sessionId };
743
+ associationProperties = { ...associationProperties, "session_id": JSON.stringify(sessionId) };
742
744
  }
743
745
  if (userId) {
744
- associationProperties = { ...associationProperties, "user_id": userId };
746
+ associationProperties = { ...associationProperties, "user_id": JSON.stringify(userId) };
745
747
  }
746
748
  let entityContext = contextApi.active();
747
749
  const currentAssociationProperties = entityContext.getValue(ASSOCIATION_PROPERTIES_KEY);
@@ -753,6 +755,84 @@ var Laminar = class {
753
755
  }
754
756
  return entityContext;
755
757
  }
758
+ /**
759
+ * Sets the session information for the current span and returns the
760
+ * context to use for the following spans. Returns the result of the
761
+ * function execution, so can be used in an `await` statement.
762
+ *
763
+ * @param sessionId - The session ID to associate with the context.
764
+ * @param fn - Function to execute within the session context.
765
+ * @returns The result of the function execution.
766
+ *
767
+ * @example
768
+ * import { Laminar, observe } from '@lmnr-ai/lmnr';
769
+ * const result = await Laminar.withSession("session1234", async () => {
770
+ * // Your code here
771
+ * });
772
+ */
773
+ static withSession(sessionId, fn) {
774
+ const currentSpan = trace3.getActiveSpan();
775
+ if (currentSpan !== void 0 && isSpanContextValid(currentSpan.spanContext())) {
776
+ if (sessionId) {
777
+ currentSpan.setAttribute(SESSION_ID, JSON.stringify(sessionId));
778
+ }
779
+ }
780
+ let associationProperties = {};
781
+ if (sessionId) {
782
+ associationProperties = { ...associationProperties, "session_id": JSON.stringify(sessionId) };
783
+ }
784
+ let entityContext = contextApi.active();
785
+ const currentAssociationProperties = entityContext.getValue(ASSOCIATION_PROPERTIES_KEY);
786
+ if (associationProperties && Object.keys(associationProperties).length > 0) {
787
+ entityContext = entityContext.setValue(
788
+ ASSOCIATION_PROPERTIES_KEY,
789
+ { ...currentAssociationProperties != null ? currentAssociationProperties : {}, ...associationProperties }
790
+ );
791
+ }
792
+ return contextApi.with(entityContext, fn);
793
+ }
794
+ /**
795
+ * Sets the metadata for the current span and returns the context to use for
796
+ * the following spans. Returns the result of the function execution, so can
797
+ * be used in an `await` statement.
798
+ *
799
+ * @param metadata - The metadata to associate with the context. Will be sent
800
+ * as attributes, so must be serializable to JSON.
801
+ * @param fn - Function to execute within the metadata context.
802
+ * @returns The result of the function execution.
803
+ *
804
+ * @example
805
+ * import { Laminar } from '@lmnr-ai/lmnr';
806
+ * const result = await Laminar.withMetadata(
807
+ * {
808
+ * "my_metadata_key": "my_metadata_value"
809
+ * },
810
+ * async () => {
811
+ * // Your code here
812
+ * }
813
+ * );
814
+ */
815
+ static withMetadata(metadata, fn) {
816
+ const currentSpan = trace3.getActiveSpan();
817
+ if (currentSpan !== void 0 && isSpanContextValid(currentSpan.spanContext())) {
818
+ for (const [key, value] of Object.entries(metadata)) {
819
+ currentSpan.setAttribute(`${ASSOCIATION_PROPERTIES}.metadata.${key}`, JSON.stringify(value));
820
+ }
821
+ }
822
+ let metadataAttributes = {};
823
+ for (const [key, value] of Object.entries(metadata)) {
824
+ metadataAttributes = { ...metadataAttributes, [`metadata.${key}`]: JSON.stringify(value) };
825
+ }
826
+ let entityContext = contextApi.active();
827
+ const currentAssociationProperties = entityContext.getValue(ASSOCIATION_PROPERTIES_KEY);
828
+ if (metadataAttributes && Object.keys(metadataAttributes).length > 0) {
829
+ entityContext = entityContext.setValue(
830
+ ASSOCIATION_PROPERTIES_KEY,
831
+ { ...currentAssociationProperties != null ? currentAssociationProperties : {}, ...metadataAttributes }
832
+ );
833
+ }
834
+ return contextApi.with(entityContext, fn);
835
+ }
756
836
  /**
757
837
  * Set attributes for the current span. Useful for manual
758
838
  * instrumentation.
@@ -775,7 +855,7 @@ var Laminar = class {
775
855
  const currentSpan = trace3.getActiveSpan();
776
856
  if (currentSpan !== void 0 && isSpanContextValid(currentSpan.spanContext())) {
777
857
  for (const [key, value] of Object.entries(attributes)) {
778
- currentSpan.setAttribute(key, value);
858
+ currentSpan.setAttribute(key, JSON.stringify(value));
779
859
  }
780
860
  }
781
861
  }