lmnr-cli 0.1.0-alpha.0 → 0.1.1

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.cjs CHANGED
@@ -45,7 +45,7 @@ let readline = require("readline");
45
45
  readline = __toESM(readline);
46
46
 
47
47
  //#region package.json
48
- var version$1 = "0.1.0-alpha.0";
48
+ var version$1 = "0.1.1";
49
49
 
50
50
  //#endregion
51
51
  //#region ../../node_modules/.pnpm/dotenv@17.2.3/node_modules/dotenv/package.json
@@ -392,7 +392,7 @@ var require_main = /* @__PURE__ */ __commonJSMin(((exports, module) => {
392
392
  //#endregion
393
393
  //#region ../client/dist/index.mjs
394
394
  var import_main = require_main();
395
- var version = "0.8.2";
395
+ var version = "0.8.3";
396
396
  function getLangVersion() {
397
397
  if (typeof process !== "undefined" && process.versions && process.versions.node) return `node-${process.versions.node}`;
398
398
  if (typeof navigator !== "undefined" && navigator.userAgent) return `browser-${navigator.userAgent}`;
@@ -1495,6 +1495,10 @@ const TS_JS_EXTENSIONS = [
1495
1495
  ".cts"
1496
1496
  ];
1497
1497
  const EXTENSIONS_TO_DISCOVER_METADATA = [...TS_JS_EXTENSIONS, ".py"];
1498
+ const logLmnrPackageNotFoundAndExit = () => {
1499
+ logger.error("@lmnr-ai/lmnr package not found or outdated. For JS/TS projects, please install the latest version of @lmnr-ai/lmnr in your project: npm install @lmnr-ai/lmnr\nYou might need to run `lmnr-cli` from the root of your project");
1500
+ process.exit(1);
1501
+ };
1498
1502
  /**
1499
1503
  * Discovers function metadata for TypeScript and JavaScript files by:
1500
1504
  * 1. Extracting TypeScript metadata (params with types from source - TS only)
@@ -1506,9 +1510,22 @@ const EXTENSIONS_TO_DISCOVER_METADATA = [...TS_JS_EXTENSIONS, ".py"];
1506
1510
  * parameter extraction via regex still works (param names without types).
1507
1511
  */
1508
1512
  const discoverTypeScriptMetadata = async (filePath, options) => {
1509
- const lmnrPackage = "@lmnr-ai/lmnr";
1510
- const { extractRolloutFunctions } = require(`${lmnrPackage}/dist/cli/worker/ts-parser.cjs`);
1511
- const { buildFile, loadModule, selectRolloutFunction } = require(`${lmnrPackage}/dist/cli/worker/build.cjs`);
1513
+ let extractRolloutFunctions;
1514
+ let buildFile;
1515
+ let loadModule;
1516
+ let selectRolloutFunction;
1517
+ try {
1518
+ const lmnrPackage = "@lmnr-ai/lmnr";
1519
+ extractRolloutFunctions = require(`${lmnrPackage}/dist/cli/worker/ts-parser.cjs`).extractRolloutFunctions;
1520
+ const buildModule = require(`${lmnrPackage}/dist/cli/worker/build.cjs`);
1521
+ buildFile = buildModule.buildFile;
1522
+ loadModule = buildModule.loadModule;
1523
+ selectRolloutFunction = buildModule.selectRolloutFunction;
1524
+ if (!extractRolloutFunctions || !buildFile || !loadModule || !selectRolloutFunction) logLmnrPackageNotFoundAndExit();
1525
+ } catch (error) {
1526
+ if (error.code === "MODULE_NOT_FOUND") logLmnrPackageNotFoundAndExit();
1527
+ throw error;
1528
+ }
1512
1529
  let paramsMetadata;
1513
1530
  try {
1514
1531
  paramsMetadata = extractRolloutFunctions(filePath);
@@ -1516,12 +1533,13 @@ const discoverTypeScriptMetadata = async (filePath, options) => {
1516
1533
  } catch (error) {
1517
1534
  logger.warn("Failed to extract TypeScript metadata, falling back to runtime parsing: " + (error instanceof Error ? error.message : String(error)));
1518
1535
  }
1536
+ const moduleText = await buildFile(filePath, {
1537
+ externalPackages: options.externalPackages,
1538
+ dynamicImportsToSkip: options.dynamicImportsToSkip
1539
+ });
1519
1540
  loadModule({
1520
1541
  filename: filePath,
1521
- moduleText: await buildFile(filePath, {
1522
- externalPackages: options.externalPackages,
1523
- dynamicImportsToSkip: options.dynamicImportsToSkip
1524
- })
1542
+ moduleText
1525
1543
  });
1526
1544
  const selectedFunction = selectRolloutFunction(options.function);
1527
1545
  if (paramsMetadata) {
@@ -1780,6 +1798,7 @@ const handleRunEvent = async (event, sessionId, filePathOrModule, client, cacheS
1780
1798
  async function runDev(filePath, options = {}) {
1781
1799
  const isPythonModule = !!options.pythonModule;
1782
1800
  const filePathOrModule = filePath || options.pythonModule;
1801
+ let didLogHandshake = false;
1783
1802
  const sessionId = newUUID();
1784
1803
  const client = new LaminarClient({
1785
1804
  baseUrl: options.baseUrl,
@@ -1869,7 +1888,8 @@ async function runDev(filePath, options = {}) {
1869
1888
  const projectId = event.data.project_id;
1870
1889
  const sessionId$1 = event.data.session_id;
1871
1890
  const frontendUrl = getFrontendUrl(options.baseUrl, options.frontendPort);
1872
- logger.info(`View your session at ${frontendUrl}/project/${projectId}/rollout-sessions/${sessionId$1}`);
1891
+ if (!didLogHandshake) logger.info(`View your session at ${frontendUrl}/project/${projectId}/rollout-sessions/${sessionId$1}`);
1892
+ didLogHandshake = true;
1873
1893
  });
1874
1894
  sseClient.on("error", (error) => {
1875
1895
  logger.warn(`Error connecting to backend: ${error.message}`);
@@ -1 +1 @@
1
- {"version":3,"file":"index.cjs","names":["path","crypto","initializeLogger","newUUID","logger$1","logger","metadata: CacheMetadata","path","response: CacheServerResponse","EventEmitter","error: any","runEvent: RolloutRunEvent","handshakeEvent: RolloutHandshakeEvent","logger","child: ChildProcess","result: any","message: WorkerMessage","config","DEFAULT_WORKERS: Record<string, WorkerCommand>","paramsMetadata: Map<string, FunctionMetadata> | undefined","foundMetadata: FunctionMetadata | null","spawn","spansByPath: Record<string, any[]>","path","cachedSpan: CachedSpan","env: Record<string, string>","workerConfig: WorkerConfig","error: any","error","params: RolloutParam[]","sseClient: SSEClient | null","sessionId","Command","version"],"sources":["../package.json","../../../node_modules/.pnpm/dotenv@17.2.3/node_modules/dotenv/package.json","../../../node_modules/.pnpm/dotenv@17.2.3/node_modules/dotenv/lib/main.js","../../client/dist/index.mjs","../src/cache-server.ts","../src/sse-client.ts","../../types/dist/index.mjs","../src/utils.ts","../src/subprocess/executor.ts","../src/worker-registry.ts","../src/commands/dev.ts","../src/index.ts"],"sourcesContent":["","","const fs = require('fs')\nconst path = require('path')\nconst os = require('os')\nconst crypto = require('crypto')\nconst packageJson = require('../package.json')\n\nconst version = packageJson.version\n\n// Array of tips to display randomly\nconst TIPS = [\n '🔐 encrypt with Dotenvx: https://dotenvx.com',\n '🔐 prevent committing .env to code: https://dotenvx.com/precommit',\n '🔐 prevent building .env in docker: https://dotenvx.com/prebuild',\n '📡 add observability to secrets: https://dotenvx.com/ops',\n '👥 sync secrets across teammates & machines: https://dotenvx.com/ops',\n '🗂️ backup and recover secrets: https://dotenvx.com/ops',\n '✅ audit secrets and track compliance: https://dotenvx.com/ops',\n '🔄 add secrets lifecycle management: https://dotenvx.com/ops',\n '🔑 add access controls to secrets: https://dotenvx.com/ops',\n '🛠️ run anywhere with `dotenvx run -- yourcommand`',\n '⚙️ specify custom .env file path with { path: \\'/custom/path/.env\\' }',\n '⚙️ enable debug logging with { debug: true }',\n '⚙️ override existing env vars with { override: true }',\n '⚙️ suppress all logs with { quiet: true }',\n '⚙️ write to custom object with { processEnv: myObject }',\n '⚙️ load multiple .env files with { path: [\\'.env.local\\', \\'.env\\'] }'\n]\n\n// Get a random tip from the tips array\nfunction _getRandomTip () {\n return TIPS[Math.floor(Math.random() * TIPS.length)]\n}\n\nfunction parseBoolean (value) {\n if (typeof value === 'string') {\n return !['false', '0', 'no', 'off', ''].includes(value.toLowerCase())\n }\n return Boolean(value)\n}\n\nfunction supportsAnsi () {\n return process.stdout.isTTY // && process.env.TERM !== 'dumb'\n}\n\nfunction dim (text) {\n return supportsAnsi() ? `\\x1b[2m${text}\\x1b[0m` : text\n}\n\nconst LINE = /(?:^|^)\\s*(?:export\\s+)?([\\w.-]+)(?:\\s*=\\s*?|:\\s+?)(\\s*'(?:\\\\'|[^'])*'|\\s*\"(?:\\\\\"|[^\"])*\"|\\s*`(?:\\\\`|[^`])*`|[^#\\r\\n]+)?\\s*(?:#.*)?(?:$|$)/mg\n\n// Parse src into an Object\nfunction parse (src) {\n const obj = {}\n\n // Convert buffer to string\n let lines = src.toString()\n\n // Convert line breaks to same format\n lines = lines.replace(/\\r\\n?/mg, '\\n')\n\n let match\n while ((match = LINE.exec(lines)) != null) {\n const key = match[1]\n\n // Default undefined or null to empty string\n let value = (match[2] || '')\n\n // Remove whitespace\n value = value.trim()\n\n // Check if double quoted\n const maybeQuote = value[0]\n\n // Remove surrounding quotes\n value = value.replace(/^(['\"`])([\\s\\S]*)\\1$/mg, '$2')\n\n // Expand newlines if double quoted\n if (maybeQuote === '\"') {\n value = value.replace(/\\\\n/g, '\\n')\n value = value.replace(/\\\\r/g, '\\r')\n }\n\n // Add to object\n obj[key] = value\n }\n\n return obj\n}\n\nfunction _parseVault (options) {\n options = options || {}\n\n const vaultPath = _vaultPath(options)\n options.path = vaultPath // parse .env.vault\n const result = DotenvModule.configDotenv(options)\n if (!result.parsed) {\n const err = new Error(`MISSING_DATA: Cannot parse ${vaultPath} for an unknown reason`)\n err.code = 'MISSING_DATA'\n throw err\n }\n\n // handle scenario for comma separated keys - for use with key rotation\n // example: DOTENV_KEY=\"dotenv://:key_1234@dotenvx.com/vault/.env.vault?environment=prod,dotenv://:key_7890@dotenvx.com/vault/.env.vault?environment=prod\"\n const keys = _dotenvKey(options).split(',')\n const length = keys.length\n\n let decrypted\n for (let i = 0; i < length; i++) {\n try {\n // Get full key\n const key = keys[i].trim()\n\n // Get instructions for decrypt\n const attrs = _instructions(result, key)\n\n // Decrypt\n decrypted = DotenvModule.decrypt(attrs.ciphertext, attrs.key)\n\n break\n } catch (error) {\n // last key\n if (i + 1 >= length) {\n throw error\n }\n // try next key\n }\n }\n\n // Parse decrypted .env string\n return DotenvModule.parse(decrypted)\n}\n\nfunction _warn (message) {\n console.error(`[dotenv@${version}][WARN] ${message}`)\n}\n\nfunction _debug (message) {\n console.log(`[dotenv@${version}][DEBUG] ${message}`)\n}\n\nfunction _log (message) {\n console.log(`[dotenv@${version}] ${message}`)\n}\n\nfunction _dotenvKey (options) {\n // prioritize developer directly setting options.DOTENV_KEY\n if (options && options.DOTENV_KEY && options.DOTENV_KEY.length > 0) {\n return options.DOTENV_KEY\n }\n\n // secondary infra already contains a DOTENV_KEY environment variable\n if (process.env.DOTENV_KEY && process.env.DOTENV_KEY.length > 0) {\n return process.env.DOTENV_KEY\n }\n\n // fallback to empty string\n return ''\n}\n\nfunction _instructions (result, dotenvKey) {\n // Parse DOTENV_KEY. Format is a URI\n let uri\n try {\n uri = new URL(dotenvKey)\n } catch (error) {\n if (error.code === 'ERR_INVALID_URL') {\n const err = new Error('INVALID_DOTENV_KEY: Wrong format. Must be in valid uri format like dotenv://:key_1234@dotenvx.com/vault/.env.vault?environment=development')\n err.code = 'INVALID_DOTENV_KEY'\n throw err\n }\n\n throw error\n }\n\n // Get decrypt key\n const key = uri.password\n if (!key) {\n const err = new Error('INVALID_DOTENV_KEY: Missing key part')\n err.code = 'INVALID_DOTENV_KEY'\n throw err\n }\n\n // Get environment\n const environment = uri.searchParams.get('environment')\n if (!environment) {\n const err = new Error('INVALID_DOTENV_KEY: Missing environment part')\n err.code = 'INVALID_DOTENV_KEY'\n throw err\n }\n\n // Get ciphertext payload\n const environmentKey = `DOTENV_VAULT_${environment.toUpperCase()}`\n const ciphertext = result.parsed[environmentKey] // DOTENV_VAULT_PRODUCTION\n if (!ciphertext) {\n const err = new Error(`NOT_FOUND_DOTENV_ENVIRONMENT: Cannot locate environment ${environmentKey} in your .env.vault file.`)\n err.code = 'NOT_FOUND_DOTENV_ENVIRONMENT'\n throw err\n }\n\n return { ciphertext, key }\n}\n\nfunction _vaultPath (options) {\n let possibleVaultPath = null\n\n if (options && options.path && options.path.length > 0) {\n if (Array.isArray(options.path)) {\n for (const filepath of options.path) {\n if (fs.existsSync(filepath)) {\n possibleVaultPath = filepath.endsWith('.vault') ? filepath : `${filepath}.vault`\n }\n }\n } else {\n possibleVaultPath = options.path.endsWith('.vault') ? options.path : `${options.path}.vault`\n }\n } else {\n possibleVaultPath = path.resolve(process.cwd(), '.env.vault')\n }\n\n if (fs.existsSync(possibleVaultPath)) {\n return possibleVaultPath\n }\n\n return null\n}\n\nfunction _resolveHome (envPath) {\n return envPath[0] === '~' ? path.join(os.homedir(), envPath.slice(1)) : envPath\n}\n\nfunction _configVault (options) {\n const debug = parseBoolean(process.env.DOTENV_CONFIG_DEBUG || (options && options.debug))\n const quiet = parseBoolean(process.env.DOTENV_CONFIG_QUIET || (options && options.quiet))\n\n if (debug || !quiet) {\n _log('Loading env from encrypted .env.vault')\n }\n\n const parsed = DotenvModule._parseVault(options)\n\n let processEnv = process.env\n if (options && options.processEnv != null) {\n processEnv = options.processEnv\n }\n\n DotenvModule.populate(processEnv, parsed, options)\n\n return { parsed }\n}\n\nfunction configDotenv (options) {\n const dotenvPath = path.resolve(process.cwd(), '.env')\n let encoding = 'utf8'\n let processEnv = process.env\n if (options && options.processEnv != null) {\n processEnv = options.processEnv\n }\n let debug = parseBoolean(processEnv.DOTENV_CONFIG_DEBUG || (options && options.debug))\n let quiet = parseBoolean(processEnv.DOTENV_CONFIG_QUIET || (options && options.quiet))\n\n if (options && options.encoding) {\n encoding = options.encoding\n } else {\n if (debug) {\n _debug('No encoding is specified. UTF-8 is used by default')\n }\n }\n\n let optionPaths = [dotenvPath] // default, look for .env\n if (options && options.path) {\n if (!Array.isArray(options.path)) {\n optionPaths = [_resolveHome(options.path)]\n } else {\n optionPaths = [] // reset default\n for (const filepath of options.path) {\n optionPaths.push(_resolveHome(filepath))\n }\n }\n }\n\n // Build the parsed data in a temporary object (because we need to return it). Once we have the final\n // parsed data, we will combine it with process.env (or options.processEnv if provided).\n let lastError\n const parsedAll = {}\n for (const path of optionPaths) {\n try {\n // Specifying an encoding returns a string instead of a buffer\n const parsed = DotenvModule.parse(fs.readFileSync(path, { encoding }))\n\n DotenvModule.populate(parsedAll, parsed, options)\n } catch (e) {\n if (debug) {\n _debug(`Failed to load ${path} ${e.message}`)\n }\n lastError = e\n }\n }\n\n const populated = DotenvModule.populate(processEnv, parsedAll, options)\n\n // handle user settings DOTENV_CONFIG_ options inside .env file(s)\n debug = parseBoolean(processEnv.DOTENV_CONFIG_DEBUG || debug)\n quiet = parseBoolean(processEnv.DOTENV_CONFIG_QUIET || quiet)\n\n if (debug || !quiet) {\n const keysCount = Object.keys(populated).length\n const shortPaths = []\n for (const filePath of optionPaths) {\n try {\n const relative = path.relative(process.cwd(), filePath)\n shortPaths.push(relative)\n } catch (e) {\n if (debug) {\n _debug(`Failed to load ${filePath} ${e.message}`)\n }\n lastError = e\n }\n }\n\n _log(`injecting env (${keysCount}) from ${shortPaths.join(',')} ${dim(`-- tip: ${_getRandomTip()}`)}`)\n }\n\n if (lastError) {\n return { parsed: parsedAll, error: lastError }\n } else {\n return { parsed: parsedAll }\n }\n}\n\n// Populates process.env from .env file\nfunction config (options) {\n // fallback to original dotenv if DOTENV_KEY is not set\n if (_dotenvKey(options).length === 0) {\n return DotenvModule.configDotenv(options)\n }\n\n const vaultPath = _vaultPath(options)\n\n // dotenvKey exists but .env.vault file does not exist\n if (!vaultPath) {\n _warn(`You set DOTENV_KEY but you are missing a .env.vault file at ${vaultPath}. Did you forget to build it?`)\n\n return DotenvModule.configDotenv(options)\n }\n\n return DotenvModule._configVault(options)\n}\n\nfunction decrypt (encrypted, keyStr) {\n const key = Buffer.from(keyStr.slice(-64), 'hex')\n let ciphertext = Buffer.from(encrypted, 'base64')\n\n const nonce = ciphertext.subarray(0, 12)\n const authTag = ciphertext.subarray(-16)\n ciphertext = ciphertext.subarray(12, -16)\n\n try {\n const aesgcm = crypto.createDecipheriv('aes-256-gcm', key, nonce)\n aesgcm.setAuthTag(authTag)\n return `${aesgcm.update(ciphertext)}${aesgcm.final()}`\n } catch (error) {\n const isRange = error instanceof RangeError\n const invalidKeyLength = error.message === 'Invalid key length'\n const decryptionFailed = error.message === 'Unsupported state or unable to authenticate data'\n\n if (isRange || invalidKeyLength) {\n const err = new Error('INVALID_DOTENV_KEY: It must be 64 characters long (or more)')\n err.code = 'INVALID_DOTENV_KEY'\n throw err\n } else if (decryptionFailed) {\n const err = new Error('DECRYPTION_FAILED: Please check your DOTENV_KEY')\n err.code = 'DECRYPTION_FAILED'\n throw err\n } else {\n throw error\n }\n }\n}\n\n// Populate process.env with parsed values\nfunction populate (processEnv, parsed, options = {}) {\n const debug = Boolean(options && options.debug)\n const override = Boolean(options && options.override)\n const populated = {}\n\n if (typeof parsed !== 'object') {\n const err = new Error('OBJECT_REQUIRED: Please check the processEnv argument being passed to populate')\n err.code = 'OBJECT_REQUIRED'\n throw err\n }\n\n // Set process.env\n for (const key of Object.keys(parsed)) {\n if (Object.prototype.hasOwnProperty.call(processEnv, key)) {\n if (override === true) {\n processEnv[key] = parsed[key]\n populated[key] = parsed[key]\n }\n\n if (debug) {\n if (override === true) {\n _debug(`\"${key}\" is already defined and WAS overwritten`)\n } else {\n _debug(`\"${key}\" is already defined and was NOT overwritten`)\n }\n }\n } else {\n processEnv[key] = parsed[key]\n populated[key] = parsed[key]\n }\n }\n\n return populated\n}\n\nconst DotenvModule = {\n configDotenv,\n _configVault,\n _parseVault,\n config,\n decrypt,\n parse,\n populate\n}\n\nmodule.exports.configDotenv = DotenvModule.configDotenv\nmodule.exports._configVault = DotenvModule._configVault\nmodule.exports._parseVault = DotenvModule._parseVault\nmodule.exports.config = DotenvModule.config\nmodule.exports.decrypt = DotenvModule.decrypt\nmodule.exports.parse = DotenvModule.parse\nmodule.exports.populate = DotenvModule.populate\n\nmodule.exports = DotenvModule\n","import { config } from \"dotenv\";\nimport * as path from \"path\";\nimport pino from \"pino\";\nimport { PinoPretty } from \"pino-pretty\";\nimport { v4 } from \"uuid\";\n\n//#region package.json\nvar version = \"0.8.2\";\n\n//#endregion\n//#region src/version.ts\nfunction getLangVersion() {\n\tif (typeof process !== \"undefined\" && process.versions && process.versions.node) return `node-${process.versions.node}`;\n\tif (typeof navigator !== \"undefined\" && navigator.userAgent) return `browser-${navigator.userAgent}`;\n\treturn null;\n}\n\n//#endregion\n//#region src/resources/index.ts\nvar BaseResource = class {\n\tconstructor(baseHttpUrl, projectApiKey) {\n\t\tthis.baseHttpUrl = baseHttpUrl;\n\t\tthis.projectApiKey = projectApiKey;\n\t}\n\theaders() {\n\t\treturn {\n\t\t\tAuthorization: `Bearer ${this.projectApiKey}`,\n\t\t\t\"Content-Type\": \"application/json\",\n\t\t\tAccept: \"application/json\"\n\t\t};\n\t}\n\tasync handleError(response) {\n\t\tconst errorMsg = await response.text();\n\t\tthrow new Error(`${response.status} ${errorMsg}`);\n\t}\n};\n\n//#endregion\n//#region src/resources/browser-events.ts\nvar BrowserEventsResource = class extends BaseResource {\n\tconstructor(baseHttpUrl, projectApiKey) {\n\t\tsuper(baseHttpUrl, projectApiKey);\n\t}\n\tasync send({ sessionId, traceId, events }) {\n\t\tconst payload = {\n\t\t\tsessionId,\n\t\t\ttraceId,\n\t\t\tevents,\n\t\t\tsource: getLangVersion() ?? \"javascript\",\n\t\t\tsdkVersion: version\n\t\t};\n\t\tconst jsonString = JSON.stringify(payload);\n\t\tconst compressedStream = new Blob([jsonString], { type: \"application/json\" }).stream().pipeThrough(new CompressionStream(\"gzip\"));\n\t\tconst compressedData = await new Response(compressedStream).arrayBuffer();\n\t\tconst response = await fetch(this.baseHttpUrl + \"/v1/browser-sessions/events\", {\n\t\t\tmethod: \"POST\",\n\t\t\theaders: {\n\t\t\t\t...this.headers(),\n\t\t\t\t\"Content-Encoding\": \"gzip\"\n\t\t\t},\n\t\t\tbody: compressedData\n\t\t});\n\t\tif (!response.ok) await this.handleError(response);\n\t}\n};\n\n//#endregion\n//#region src/utils.ts\nfunction initializeLogger(options) {\n\tconst colorize = options?.colorize ?? true;\n\tconst level = options?.level ?? process.env.LMNR_LOG_LEVEL?.toLowerCase()?.trim() ?? \"info\";\n\treturn pino({ level }, PinoPretty({\n\t\tcolorize,\n\t\tminimumLevel: level\n\t}));\n}\nconst logger$2 = initializeLogger();\nconst isStringUUID = (id) => /^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/.test(id);\nconst newUUID = () => {\n\tif (typeof crypto !== \"undefined\" && typeof crypto.randomUUID === \"function\") return crypto.randomUUID();\n\telse return v4();\n};\nconst otelSpanIdToUUID = (spanId) => {\n\tlet id = spanId.toLowerCase();\n\tif (id.startsWith(\"0x\")) id = id.slice(2);\n\tif (id.length !== 16) logger$2.warn(`Span ID ${spanId} is not 16 hex chars long. This is not a valid OpenTelemetry span ID.`);\n\tif (!/^[0-9a-f]+$/.test(id)) {\n\t\tlogger$2.error(`Span ID ${spanId} is not a valid hex string. Generating a random UUID instead.`);\n\t\treturn newUUID();\n\t}\n\treturn id.padStart(32, \"0\").replace(/^([0-9a-f]{8})([0-9a-f]{4})([0-9a-f]{4})([0-9a-f]{4})([0-9a-f]{12})$/, \"$1-$2-$3-$4-$5\");\n};\nconst otelTraceIdToUUID = (traceId) => {\n\tlet id = traceId.toLowerCase();\n\tif (id.startsWith(\"0x\")) id = id.slice(2);\n\tif (id.length !== 32) logger$2.warn(`Trace ID ${traceId} is not 32 hex chars long. This is not a valid OpenTelemetry trace ID.`);\n\tif (!/^[0-9a-f]+$/.test(id)) {\n\t\tlogger$2.error(`Trace ID ${traceId} is not a valid hex string. Generating a random UUID instead.`);\n\t\treturn newUUID();\n\t}\n\treturn id.replace(/^([0-9a-f]{8})([0-9a-f]{4})([0-9a-f]{4})([0-9a-f]{4})([0-9a-f]{12})$/, \"$1-$2-$3-$4-$5\");\n};\nconst slicePayload = (value, length) => {\n\tif (value === null || value === void 0) return value;\n\tconst str = JSON.stringify(value);\n\tif (str.length <= length) return value;\n\treturn str.slice(0, length) + \"...\";\n};\nconst loadEnv = (options) => {\n\tconst nodeEnv = process.env.NODE_ENV || \"development\";\n\tconst envDir = process.cwd();\n\tconst envFiles = [\n\t\t\".env\",\n\t\t\".env.local\",\n\t\t`.env.${nodeEnv}`,\n\t\t`.env.${nodeEnv}.local`\n\t];\n\tconst logLevel = process.env.LMNR_LOG_LEVEL ?? \"info\";\n\tconst verbose = [\"debug\", \"trace\"].includes(logLevel.trim().toLowerCase());\n\tconst quiet = options?.quiet ?? !verbose;\n\tconfig({\n\t\tpath: options?.paths ?? envFiles.map((envFile) => path.resolve(envDir, envFile)),\n\t\tquiet\n\t});\n};\n\n//#endregion\n//#region src/resources/datasets.ts\nconst logger$1 = initializeLogger();\nconst DEFAULT_DATASET_PULL_LIMIT = 100;\nconst DEFAULT_DATASET_PUSH_BATCH_SIZE = 100;\nvar DatasetsResource = class extends BaseResource {\n\tconstructor(baseHttpUrl, projectApiKey) {\n\t\tsuper(baseHttpUrl, projectApiKey);\n\t}\n\t/**\n\t* List all datasets.\n\t*\n\t* @returns {Promise<Dataset[]>} Array of datasets\n\t*/\n\tasync listDatasets() {\n\t\tconst response = await fetch(this.baseHttpUrl + \"/v1/datasets\", {\n\t\t\tmethod: \"GET\",\n\t\t\theaders: this.headers()\n\t\t});\n\t\tif (!response.ok) await this.handleError(response);\n\t\treturn response.json();\n\t}\n\t/**\n\t* Get a dataset by name.\n\t*\n\t* @param {string} name - Name of the dataset\n\t* @returns {Promise<Dataset[]>} Array of datasets with matching name\n\t*/\n\tasync getDatasetByName(name) {\n\t\tconst params = new URLSearchParams({ name });\n\t\tconst response = await fetch(this.baseHttpUrl + `/v1/datasets?${params.toString()}`, {\n\t\t\tmethod: \"GET\",\n\t\t\theaders: this.headers()\n\t\t});\n\t\tif (!response.ok) await this.handleError(response);\n\t\treturn response.json();\n\t}\n\t/**\n\t* Push datapoints to a dataset.\n\t*\n\t* @param {Object} options - Push options\n\t* @param {Datapoint<D, T>[]} options.points - Datapoints to push\n\t* @param {string} [options.name] - Name of the dataset (either name or id must be provided)\n\t* @param {StringUUID} [options.id] - ID of the dataset (either name or id must be provided)\n\t* @param {number} [options.batchSize] - Batch size for pushing (default: 100)\n\t* @param {boolean} [options.createDataset] - Whether to create the dataset if it doesn't exist\n\t* @returns {Promise<PushDatapointsResponse | undefined>}\n\t*/\n\tasync push({ points, name, id, batchSize = DEFAULT_DATASET_PUSH_BATCH_SIZE, createDataset = false }) {\n\t\tif (!name && !id) throw new Error(\"Either name or id must be provided\");\n\t\tif (name && id) throw new Error(\"Only one of name or id must be provided\");\n\t\tif (createDataset && !name) throw new Error(\"Name must be provided when creating a new dataset\");\n\t\tconst identifier = name ? { name } : { datasetId: id };\n\t\tconst totalBatches = Math.ceil(points.length / batchSize);\n\t\tlet response;\n\t\tfor (let i = 0; i < points.length; i += batchSize) {\n\t\t\tconst batchNum = Math.floor(i / batchSize) + 1;\n\t\t\tlogger$1.debug(`Pushing batch ${batchNum} of ${totalBatches}`);\n\t\t\tconst batch = points.slice(i, i + batchSize);\n\t\t\tconst fetchResponse = await fetch(this.baseHttpUrl + \"/v1/datasets/datapoints\", {\n\t\t\t\tmethod: \"POST\",\n\t\t\t\theaders: this.headers(),\n\t\t\t\tbody: JSON.stringify({\n\t\t\t\t\t...identifier,\n\t\t\t\t\tdatapoints: batch.map((point) => ({\n\t\t\t\t\t\tdata: point.data,\n\t\t\t\t\t\ttarget: point.target ?? {},\n\t\t\t\t\t\tmetadata: point.metadata ?? {}\n\t\t\t\t\t})),\n\t\t\t\t\tcreateDataset\n\t\t\t\t})\n\t\t\t});\n\t\t\tif (fetchResponse.status !== 200 && fetchResponse.status !== 201) await this.handleError(fetchResponse);\n\t\t\tresponse = await fetchResponse.json();\n\t\t}\n\t\treturn response;\n\t}\n\t/**\n\t* Pull datapoints from a dataset.\n\t*\n\t* @param {Object} options - Pull options\n\t* @param {string} [options.name] - Name of the dataset (either name or id must be provided)\n\t* @param {StringUUID} [options.id] - ID of the dataset (either name or id must be provided)\n\t* @param {number} [options.limit] - Maximum number of datapoints to return (default: 100)\n\t* @param {number} [options.offset] - Offset for pagination (default: 0)\n\t* @returns {Promise<GetDatapointsResponse<D, T>>}\n\t*/\n\tasync pull({ name, id, limit = DEFAULT_DATASET_PULL_LIMIT, offset = 0 }) {\n\t\tif (!name && !id) throw new Error(\"Either name or id must be provided\");\n\t\tif (name && id) throw new Error(\"Only one of name or id must be provided\");\n\t\tconst paramsObj = {\n\t\t\toffset: offset.toString(),\n\t\t\tlimit: limit.toString()\n\t\t};\n\t\tif (name) paramsObj.name = name;\n\t\telse paramsObj.datasetId = id;\n\t\tconst params = new URLSearchParams(paramsObj);\n\t\tconst response = await fetch(this.baseHttpUrl + `/v1/datasets/datapoints?${params.toString()}`, {\n\t\t\tmethod: \"GET\",\n\t\t\theaders: this.headers()\n\t\t});\n\t\tif (!response.ok) await this.handleError(response);\n\t\treturn response.json();\n\t}\n};\n\n//#endregion\n//#region src/resources/evals.ts\nconst logger = initializeLogger();\nconst INITIAL_EVALUATION_DATAPOINT_MAX_DATA_LENGTH = 16e6;\nvar EvalsResource = class extends BaseResource {\n\tconstructor(baseHttpUrl, projectApiKey) {\n\t\tsuper(baseHttpUrl, projectApiKey);\n\t}\n\t/**\n\t* Initialize an evaluation.\n\t*\n\t* @param {string} name - Name of the evaluation\n\t* @param {string} groupName - Group name of the evaluation\n\t* @param {Record<string, any>} metadata - Optional metadata\n\t* @returns {Promise<InitEvaluationResponse>} Response from the evaluation initialization\n\t*/\n\tasync init(name, groupName, metadata) {\n\t\tconst response = await fetch(this.baseHttpUrl + \"/v1/evals\", {\n\t\t\tmethod: \"POST\",\n\t\t\theaders: this.headers(),\n\t\t\tbody: JSON.stringify({\n\t\t\t\tname: name ?? null,\n\t\t\t\tgroupName: groupName ?? null,\n\t\t\t\tmetadata: metadata ?? null\n\t\t\t})\n\t\t});\n\t\tif (!response.ok) await this.handleError(response);\n\t\treturn response.json();\n\t}\n\t/**\n\t* Create a new evaluation and return its ID.\n\t*\n\t* @param {string} [name] - Optional name of the evaluation\n\t* @param {string} [groupName] - An identifier to group evaluations\n\t* @param {Record<string, any>} [metadata] - Optional metadata\n\t* @returns {Promise<StringUUID>} The evaluation ID\n\t*/\n\tasync create(args) {\n\t\treturn (await this.init(args?.name, args?.groupName, args?.metadata)).id;\n\t}\n\t/**\n\t* Create a new evaluation and return its ID.\n\t* @deprecated use `create` instead.\n\t*/\n\tasync createEvaluation(name, groupName, metadata) {\n\t\treturn (await this.init(name, groupName, metadata)).id;\n\t}\n\t/**\n\t* Create a datapoint for an evaluation.\n\t*\n\t* @param {Object} options - Create datapoint options\n\t* @param {string} options.evalId - The evaluation ID\n\t* @param {D} options.data - The input data for the executor\n\t* @param {T} [options.target] - The target/expected output for evaluators\n\t* @param {Record<string, any>} [options.metadata] - Optional metadata\n\t* @param {number} [options.index] - Optional index of the datapoint\n\t* @param {string} [options.traceId] - Optional trace ID\n\t* @returns {Promise<StringUUID>} The datapoint ID\n\t*/\n\tasync createDatapoint({ evalId, data, target, metadata, index, traceId }) {\n\t\tconst datapointId = newUUID();\n\t\tconst partialDatapoint = {\n\t\t\tid: datapointId,\n\t\t\tdata,\n\t\t\ttarget,\n\t\t\tindex: index ?? 0,\n\t\t\ttraceId: traceId ?? newUUID(),\n\t\t\texecutorSpanId: newUUID(),\n\t\t\tmetadata\n\t\t};\n\t\tawait this.saveDatapoints({\n\t\t\tevalId,\n\t\t\tdatapoints: [partialDatapoint]\n\t\t});\n\t\treturn datapointId;\n\t}\n\t/**\n\t* Update a datapoint with evaluation results.\n\t*\n\t* @param {Object} options - Update datapoint options\n\t* @param {string} options.evalId - The evaluation ID\n\t* @param {string} options.datapointId - The datapoint ID\n\t* @param {Record<string, number>} options.scores - The scores\n\t* @param {O} [options.executorOutput] - The executor output\n\t* @returns {Promise<void>}\n\t*/\n\tasync updateDatapoint({ evalId, datapointId, scores, executorOutput }) {\n\t\tconst response = await fetch(this.baseHttpUrl + `/v1/evals/${evalId}/datapoints/${datapointId}`, {\n\t\t\tmethod: \"POST\",\n\t\t\theaders: this.headers(),\n\t\t\tbody: JSON.stringify({\n\t\t\t\texecutorOutput,\n\t\t\t\tscores\n\t\t\t})\n\t\t});\n\t\tif (!response.ok) await this.handleError(response);\n\t}\n\t/**\n\t* Save evaluation datapoints.\n\t*\n\t* @param {Object} options - Save datapoints options\n\t* @param {string} options.evalId - ID of the evaluation\n\t* @param {EvaluationDatapoint<D, T, O>[]} options.datapoints - Datapoint to add\n\t* @param {string} [options.groupName] - Group name of the evaluation\n\t* @returns {Promise<void>} Response from the datapoint addition\n\t*/\n\tasync saveDatapoints({ evalId, datapoints, groupName }) {\n\t\tconst response = await fetch(this.baseHttpUrl + `/v1/evals/${evalId}/datapoints`, {\n\t\t\tmethod: \"POST\",\n\t\t\theaders: this.headers(),\n\t\t\tbody: JSON.stringify({\n\t\t\t\tpoints: datapoints.map((d) => ({\n\t\t\t\t\t...d,\n\t\t\t\t\tdata: slicePayload(d.data, INITIAL_EVALUATION_DATAPOINT_MAX_DATA_LENGTH),\n\t\t\t\t\ttarget: slicePayload(d.target, INITIAL_EVALUATION_DATAPOINT_MAX_DATA_LENGTH),\n\t\t\t\t\texecutorOutput: slicePayload(d.executorOutput, INITIAL_EVALUATION_DATAPOINT_MAX_DATA_LENGTH)\n\t\t\t\t})),\n\t\t\t\tgroupName: groupName ?? null\n\t\t\t})\n\t\t});\n\t\tif (response.status === 413) return await this.retrySaveDatapoints({\n\t\t\tevalId,\n\t\t\tdatapoints,\n\t\t\tgroupName\n\t\t});\n\t\tif (!response.ok) await this.handleError(response);\n\t}\n\t/**\n\t* Get evaluation datapoints.\n\t*\n\t* @deprecated Use `client.datasets.pull()` instead.\n\t* @param {Object} options - Get datapoints options\n\t* @param {string} options.datasetName - Name of the dataset\n\t* @param {number} options.offset - Offset at which to start the query\n\t* @param {number} options.limit - Maximum number of datapoints to return\n\t* @returns {Promise<GetDatapointsResponse>} Response from the datapoint retrieval\n\t*/\n\tasync getDatapoints({ datasetName, offset, limit }) {\n\t\tlogger.warn(\"evals.getDatapoints() is deprecated. Use client.datasets.pull() instead.\");\n\t\tconst params = new URLSearchParams({\n\t\t\tname: datasetName,\n\t\t\toffset: offset.toString(),\n\t\t\tlimit: limit.toString()\n\t\t});\n\t\tconst response = await fetch(this.baseHttpUrl + `/v1/datasets/datapoints?${params.toString()}`, {\n\t\t\tmethod: \"GET\",\n\t\t\theaders: this.headers()\n\t\t});\n\t\tif (!response.ok) await this.handleError(response);\n\t\treturn await response.json();\n\t}\n\tasync retrySaveDatapoints({ evalId, datapoints, groupName, maxRetries = 25, initialLength = INITIAL_EVALUATION_DATAPOINT_MAX_DATA_LENGTH }) {\n\t\tlet length = initialLength;\n\t\tlet lastResponse = null;\n\t\tfor (let i = 0; i < maxRetries; i++) {\n\t\t\tlogger.debug(`Retrying save datapoints... ${i + 1} of ${maxRetries}, length: ${length}`);\n\t\t\tconst response = await fetch(this.baseHttpUrl + `/v1/evals/${evalId}/datapoints`, {\n\t\t\t\tmethod: \"POST\",\n\t\t\t\theaders: this.headers(),\n\t\t\t\tbody: JSON.stringify({\n\t\t\t\t\tpoints: datapoints.map((d) => ({\n\t\t\t\t\t\t...d,\n\t\t\t\t\t\tdata: slicePayload(d.data, length),\n\t\t\t\t\t\ttarget: slicePayload(d.target, length),\n\t\t\t\t\t\texecutorOutput: slicePayload(d.executorOutput, length)\n\t\t\t\t\t})),\n\t\t\t\t\tgroupName: groupName ?? null\n\t\t\t\t})\n\t\t\t});\n\t\t\tlastResponse = response;\n\t\t\tlength = Math.floor(length / 2);\n\t\t\tif (response.status !== 413) break;\n\t\t}\n\t\tif (lastResponse && !lastResponse.ok) await this.handleError(lastResponse);\n\t}\n};\n\n//#endregion\n//#region src/resources/evaluators.ts\nvar EvaluatorScoreSourceType = /* @__PURE__ */ function(EvaluatorScoreSourceType$1) {\n\tEvaluatorScoreSourceType$1[\"Evaluator\"] = \"Evaluator\";\n\tEvaluatorScoreSourceType$1[\"Code\"] = \"Code\";\n\treturn EvaluatorScoreSourceType$1;\n}(EvaluatorScoreSourceType || {});\n/**\n* Resource for creating evaluator scores\n*/\nvar EvaluatorsResource = class extends BaseResource {\n\tconstructor(baseHttpUrl, projectApiKey) {\n\t\tsuper(baseHttpUrl, projectApiKey);\n\t}\n\t/**\n\t* Create a score for a span or trace\n\t*\n\t* @param {ScoreOptions} options - Score creation options\n\t* @param {string} options.name - Name of the score\n\t* @param {string} [options.traceId] - The trace ID to score (will be attached to top-level span)\n\t* @param {string} [options.spanId] - The span ID to score\n\t* @param {Record<string, any>} [options.metadata] - Additional metadata\n\t* @param {number} options.score - The score value (float)\n\t* @returns {Promise<void>}\n\t*\n\t* @example\n\t* // Score by trace ID (will attach to root span)\n\t* await evaluators.score({\n\t* name: \"quality\",\n\t* traceId: \"trace-id-here\",\n\t* score: 0.95,\n\t* metadata: { model: \"gpt-4\" }\n\t* });\n\t*\n\t* @example\n\t* // Score by span ID\n\t* await evaluators.score({\n\t* name: \"relevance\",\n\t* spanId: \"span-id-here\",\n\t* score: 0.87\n\t* });\n\t*/\n\tasync score(options) {\n\t\tconst { name, metadata, score } = options;\n\t\tlet payload;\n\t\tif (\"traceId\" in options && options.traceId) {\n\t\t\tconst formattedTraceId = isStringUUID(options.traceId) ? options.traceId : otelTraceIdToUUID(options.traceId);\n\t\t\tpayload = {\n\t\t\t\tname,\n\t\t\t\tmetadata,\n\t\t\t\tscore,\n\t\t\t\tsource: EvaluatorScoreSourceType.Code,\n\t\t\t\ttraceId: formattedTraceId\n\t\t\t};\n\t\t} else if (\"spanId\" in options && options.spanId) {\n\t\t\tconst formattedSpanId = isStringUUID(options.spanId) ? options.spanId : otelSpanIdToUUID(options.spanId);\n\t\t\tpayload = {\n\t\t\t\tname,\n\t\t\t\tmetadata,\n\t\t\t\tscore,\n\t\t\t\tsource: EvaluatorScoreSourceType.Code,\n\t\t\t\tspanId: formattedSpanId\n\t\t\t};\n\t\t} else throw new Error(\"Either 'traceId' or 'spanId' must be provided.\");\n\t\tconst response = await fetch(this.baseHttpUrl + \"/v1/evaluators/score\", {\n\t\t\tmethod: \"POST\",\n\t\t\theaders: this.headers(),\n\t\t\tbody: JSON.stringify(payload)\n\t\t});\n\t\tif (!response.ok) await this.handleError(response);\n\t}\n};\n\n//#endregion\n//#region src/resources/rollout-sessions.ts\nvar RolloutSessionsResource = class extends BaseResource {\n\tconstructor(baseHttpUrl, projectApiKey) {\n\t\tsuper(baseHttpUrl, projectApiKey);\n\t}\n\t/**\n\t* Connects to the SSE stream for rollout debugging sessions\n\t* Returns the Response object for streaming SSE events\n\t*/\n\tasync connect({ sessionId, name, params, signal }) {\n\t\tconst response = await fetch(`${this.baseHttpUrl}/v1/rollouts/${sessionId}`, {\n\t\t\tmethod: \"POST\",\n\t\t\theaders: {\n\t\t\t\t...this.headers(),\n\t\t\t\t\"Accept\": \"text/event-stream\"\n\t\t\t},\n\t\t\tbody: JSON.stringify({\n\t\t\t\tname,\n\t\t\t\tparams\n\t\t\t}),\n\t\t\tsignal\n\t\t});\n\t\tif (!response.ok) throw new Error(`SSE connection failed: ${response.status} ${response.statusText}`);\n\t\tif (!response.body) throw new Error(\"No response body\");\n\t\treturn response;\n\t}\n\tasync delete({ sessionId }) {\n\t\tconst response = await fetch(`${this.baseHttpUrl}/v1/rollouts/${sessionId}`, {\n\t\t\tmethod: \"DELETE\",\n\t\t\theaders: this.headers()\n\t\t});\n\t\tif (!response.ok) await this.handleError(response);\n\t}\n\tasync setStatus({ sessionId, status }) {\n\t\tconst response = await fetch(`${this.baseHttpUrl}/v1/rollouts/${sessionId}/status`, {\n\t\t\tmethod: \"PATCH\",\n\t\t\theaders: this.headers(),\n\t\t\tbody: JSON.stringify({ status })\n\t\t});\n\t\tif (!response.ok) await this.handleError(response);\n\t}\n\tasync sendSpanUpdate({ sessionId, span }) {\n\t\tconst response = await fetch(`${this.baseHttpUrl}/v1/rollouts/${sessionId}/update`, {\n\t\t\tmethod: \"PATCH\",\n\t\t\theaders: this.headers(),\n\t\t\tbody: JSON.stringify({\n\t\t\t\ttype: \"spanStart\",\n\t\t\t\tspanId: otelSpanIdToUUID(span.spanId),\n\t\t\t\ttraceId: otelTraceIdToUUID(span.traceId),\n\t\t\t\tparentSpanId: span.parentSpanId ? otelSpanIdToUUID(span.parentSpanId) : void 0,\n\t\t\t\tattributes: span.attributes,\n\t\t\t\tstartTime: span.startTime,\n\t\t\t\tname: span.name,\n\t\t\t\tspanType: span.spanType\n\t\t\t})\n\t\t});\n\t\tif (!response.ok) await this.handleError(response);\n\t}\n};\n\n//#endregion\n//#region src/resources/sql.ts\nvar SqlResource = class extends BaseResource {\n\tconstructor(baseHttpUrl, projectApiKey) {\n\t\tsuper(baseHttpUrl, projectApiKey);\n\t}\n\tasync query(sql, parameters = {}) {\n\t\tconst response = await fetch(`${this.baseHttpUrl}/v1/sql/query`, {\n\t\t\tmethod: \"POST\",\n\t\t\theaders: { ...this.headers() },\n\t\t\tbody: JSON.stringify({\n\t\t\t\tquery: sql,\n\t\t\t\tparameters\n\t\t\t})\n\t\t});\n\t\tif (!response.ok) await this.handleError(response);\n\t\treturn (await response.json()).data;\n\t}\n};\n\n//#endregion\n//#region src/resources/tags.ts\n/** Resource for tagging traces. */\nvar TagsResource = class extends BaseResource {\n\t/** Resource for tagging traces. */\n\tconstructor(baseHttpUrl, projectApiKey) {\n\t\tsuper(baseHttpUrl, projectApiKey);\n\t}\n\t/**\n\t* Tag a trace with a list of tags. Note that the trace must be ended before\n\t* tagging it. You may want to call `await Laminar.flush()` after the trace\n\t* that you want to tag.\n\t*\n\t* @param {string | StringUUID} trace_id - The trace id to tag.\n\t* @param {string[] | string} tags - The tag or list of tags to add to the trace.\n\t* @returns {Promise<any>} The response from the server.\n\t* @example\n\t* ```javascript\n\t* import { Laminar, observe, LaminarClient } from \"@lmnr-ai/lmnr\";\n\t* Laminar.initialize();\n\t* const client = new LaminarClient();\n\t* let traceId: StringUUID | null = null;\n\t* // Make sure this is called outside of traced context.\n\t* await observe(\n\t* {\n\t* name: \"my-trace\",\n\t* },\n\t* async () => {\n\t* traceId = await Laminar.getTraceId();\n\t* await foo();\n\t* },\n\t* );\n\t*\n\t* // or make sure the trace is ended by this point.\n\t* await Laminar.flush();\n\t* if (traceId) {\n\t* await client.tags.tag(traceId, [\"tag1\", \"tag2\"]);\n\t* }\n\t* ```\n\t*/\n\tasync tag(trace_id, tags) {\n\t\tconst traceTags = Array.isArray(tags) ? tags : [tags];\n\t\tconst formattedTraceId = isStringUUID(trace_id) ? trace_id : otelTraceIdToUUID(trace_id);\n\t\tconst url = this.baseHttpUrl + \"/v1/tag\";\n\t\tconst payload = {\n\t\t\t\"traceId\": formattedTraceId,\n\t\t\t\"names\": traceTags\n\t\t};\n\t\tconst response = await fetch(url, {\n\t\t\tmethod: \"POST\",\n\t\t\theaders: this.headers(),\n\t\t\tbody: JSON.stringify(payload)\n\t\t});\n\t\tif (!response.ok) await this.handleError(response);\n\t\treturn response.json();\n\t}\n};\n\n//#endregion\n//#region src/index.ts\nvar LaminarClient = class {\n\tconstructor({ baseUrl, projectApiKey, port } = {}) {\n\t\tloadEnv();\n\t\tthis.projectApiKey = projectApiKey ?? process.env.LMNR_PROJECT_API_KEY;\n\t\tconst httpPort = port ?? (baseUrl?.match(/:\\d{1,5}$/g) ? parseInt(baseUrl.match(/:\\d{1,5}$/g)[0].slice(1)) : 443);\n\t\tthis.baseUrl = `${(baseUrl ?? process.env.LMNR_BASE_URL)?.replace(/\\/$/, \"\").replace(/:\\d{1,5}$/g, \"\") ?? \"https://api.lmnr.ai\"}:${httpPort}`;\n\t\tthis._browserEvents = new BrowserEventsResource(this.baseUrl, this.projectApiKey);\n\t\tthis._datasets = new DatasetsResource(this.baseUrl, this.projectApiKey);\n\t\tthis._evals = new EvalsResource(this.baseUrl, this.projectApiKey);\n\t\tthis._evaluators = new EvaluatorsResource(this.baseUrl, this.projectApiKey);\n\t\tthis._rolloutSessions = new RolloutSessionsResource(this.baseUrl, this.projectApiKey);\n\t\tthis._sql = new SqlResource(this.baseUrl, this.projectApiKey);\n\t\tthis._tags = new TagsResource(this.baseUrl, this.projectApiKey);\n\t}\n\tget browserEvents() {\n\t\treturn this._browserEvents;\n\t}\n\tget datasets() {\n\t\treturn this._datasets;\n\t}\n\tget evals() {\n\t\treturn this._evals;\n\t}\n\tget evaluators() {\n\t\treturn this._evaluators;\n\t}\n\tget rolloutSessions() {\n\t\treturn this._rolloutSessions;\n\t}\n\tget sql() {\n\t\treturn this._sql;\n\t}\n\tget tags() {\n\t\treturn this._tags;\n\t}\n};\n\n//#endregion\nexport { LaminarClient };\n//# sourceMappingURL=index.mjs.map","import {\n CachedSpan,\n CacheMetadata,\n CacheServerResponse,\n} from '@lmnr-ai/types';\nimport * as http from 'http';\n\ninterface CacheServerResult {\n port: number;\n server: http.Server;\n cache: Map<string, CachedSpan>;\n setMetadata: (metadata: CacheMetadata) => void;\n}\n\nconst DEFAULT_START_PORT = 35667;\n\n/**\n * Finds an available port starting from the given port number\n */\nasync function findAvailablePort(startPort: number): Promise<number> {\n return new Promise((resolve, reject) => {\n const server = http.createServer();\n\n server.listen(startPort, () => {\n const port = (server.address() as any).port;\n server.close(() => resolve(port));\n });\n\n server.on('error', (err: any) => {\n if (err.code === 'EADDRINUSE') {\n // Port is in use, try the next one\n resolve(findAvailablePort(startPort + 1));\n } else {\n reject(err as Error);\n }\n });\n });\n}\n\n/**\n * Parses request body as JSON\n */\nfunction parseBody(req: http.IncomingMessage): Promise<any> {\n return new Promise((resolve, reject) => {\n let body = '';\n\n req.on('data', (chunk) => {\n body += chunk.toString();\n });\n\n req.on('end', () => {\n try {\n resolve(body ? JSON.parse(body) : {});\n } catch (err) {\n reject(new Error(`Invalid JSON: ${err instanceof Error ? err.message : String(err)}`));\n }\n });\n\n req.on('error', reject);\n });\n}\n\n/**\n * Starts a local cache server for storing and retrieving cached LLM responses\n * during rollout debugging sessions.\n *\n * @param startPort - Optional starting port number (defaults to 35667)\n * @returns Server information including port, server instance, cache, and metadata setter\n */\nexport async function startCacheServer(\n startPort: number = DEFAULT_START_PORT,\n): Promise<CacheServerResult> {\n const cache = new Map<string, CachedSpan>();\n let metadata: CacheMetadata = {\n pathToCount: {},\n overrides: undefined,\n };\n\n const server = http.createServer((req, res) => {\n (async () => {\n // Set CORS headers for local development\n res.setHeader('Access-Control-Allow-Origin', '*');\n res.setHeader('Access-Control-Allow-Methods', 'GET, POST, OPTIONS');\n res.setHeader('Access-Control-Allow-Headers', 'Content-Type');\n\n // Handle preflight requests\n if (req.method === 'OPTIONS') {\n res.writeHead(200);\n res.end();\n return;\n }\n\n // Health check endpoint\n if (req.method === 'GET' && req.url === '/health') {\n res.writeHead(200, { 'Content-Type': 'application/json' });\n res.end(JSON.stringify({ status: 'ok' }));\n return;\n }\n\n // Cached response endpoint\n if (req.method === 'POST' && req.url === '/cached') {\n try {\n const body = await parseBody(req);\n const { path, index } = body;\n\n if (typeof path !== 'string' || typeof index !== 'number') {\n res.writeHead(400, { 'Content-Type': 'application/json' });\n res.end(JSON.stringify(\n { error: 'Invalid request: path (string) and index (number) required' },\n ));\n return;\n }\n\n // Cache key is ${index}:${path} to handle colons in paths\n const cacheKey = `${index}:${path}`;\n const cachedSpan = cache.get(cacheKey);\n\n // Return cached span with metadata\n const response: CacheServerResponse = {\n span: cachedSpan,\n pathToCount: metadata.pathToCount,\n overrides: metadata.overrides,\n };\n\n res.writeHead(200, { 'Content-Type': 'application/json' });\n res.end(JSON.stringify(response));\n } catch (err) {\n res.writeHead(400, { 'Content-Type': 'application/json' });\n res.end(JSON.stringify(\n { error: err instanceof Error ? err.message : String(err) },\n ));\n }\n return;\n }\n\n // 404 for unknown routes\n res.writeHead(404, { 'Content-Type': 'application/json' });\n res.end(JSON.stringify({ error: 'Not found' }));\n })().catch((error) => {\n // Catch any unexpected errors and send 500 response\n if (!res.headersSent) {\n res.writeHead(500, { 'Content-Type': 'application/json' });\n res.end(JSON.stringify({\n error: error instanceof Error ? error.message : 'Internal server error',\n }));\n }\n });\n });\n\n const port = await findAvailablePort(startPort);\n\n return new Promise((resolve, reject) => {\n server.listen(port, () => {\n resolve({\n port,\n server,\n cache,\n setMetadata: (newMetadata: CacheMetadata) => {\n metadata = newMetadata;\n },\n });\n });\n\n server.on('error', reject);\n });\n}\n","import { LaminarClient } from '@lmnr-ai/client';\nimport { RolloutHandshakeEvent, RolloutParam, RolloutRunEvent } from '@lmnr-ai/types';\nimport { EventEmitter } from 'events';\nimport { createParser } from 'eventsource-parser';\n\nconst HEARTBEAT_INTERVAL = 5000; // 5 seconds\nconst MAX_MISSED_HEARTBEATS = 3; // N missed intervals before reconnect\n\nexport interface SSEClientOptions {\n client: LaminarClient;\n sessionId: string;\n params: RolloutParam[];\n name: string;\n}\n\n/**\n * SSE client for rollout debugging sessions\n * Connects to the Laminar backend and listens for run events\n */\nexport class SSEClient extends EventEmitter {\n private client: LaminarClient;\n private sessionId: string;\n private params: RolloutParam[];\n private name: string;\n private abortController?: AbortController;\n private reconnectTimer?: NodeJS.Timeout;\n private lastHeartbeat: number = Date.now();\n private heartbeatCheckTimer?: NodeJS.Timeout;\n private isShutdown: boolean = false;\n\n constructor(options: SSEClientOptions) {\n super();\n this.client = options.client;\n this.sessionId = options.sessionId;\n this.params = options.params;\n this.name = options.name;\n }\n\n /**\n * Connects to the SSE endpoint\n */\n async connectAndListen(): Promise<void> {\n if (this.isShutdown) {\n return;\n }\n\n this.abortController = new AbortController();\n this.lastHeartbeat = Date.now();\n\n try {\n const response = await this.client.rolloutSessions.connect({\n sessionId: this.sessionId,\n params: this.params,\n signal: this.abortController.signal,\n name: this.name,\n });\n\n this.emit('connected');\n this.startHeartbeatCheck();\n\n // Parse SSE stream\n await this.parseSSEStream(response.body!);\n } catch (error: any) {\n if (error.name === 'AbortError') {\n // Connection was aborted intentionally\n return;\n }\n\n this.emit('error', error);\n\n if (!this.isShutdown) {\n // Attempt to reconnect\n this.scheduleReconnect();\n }\n }\n }\n\n /**\n * Parses SSE stream and emits events\n */\n private async parseSSEStream(body: ReadableStream<Uint8Array>): Promise<void> {\n const reader = body.getReader();\n const decoder = new TextDecoder();\n\n // Create SSE parser with proper event handling\n const parser = createParser({\n onEvent: (event: any) => {\n this.processSSEEvent(event);\n },\n });\n\n try {\n while (true) {\n const { done, value } = await reader.read();\n\n if (done) {\n break;\n }\n\n // Feed the chunks to the parser\n const chunk = decoder.decode(value, { stream: true });\n parser.feed(chunk);\n }\n } finally {\n reader.releaseLock();\n }\n\n // Connection ended, try to reconnect if not shutdown\n if (!this.isShutdown) {\n this.scheduleReconnect();\n }\n }\n\n /**\n * Processes a parsed SSE event\n */\n private processSSEEvent(event: any): void {\n if (!event.data) {\n return;\n }\n\n try {\n // The event.event field contains the event type ('heartbeat' or 'run')\n // The event.data field contains the JSON payload\n if (event.event === 'heartbeat') {\n this.lastHeartbeat = Date.now();\n this.emit('heartbeat');\n } else if (event.event === 'run') {\n const parsedData = JSON.parse(event.data);\n const runEvent: RolloutRunEvent = {\n event_type: 'run',\n data: parsedData,\n };\n this.emit('run', runEvent);\n } else if (event.event === 'handshake') {\n const parsedData = JSON.parse(event.data);\n const handshakeEvent: RolloutHandshakeEvent = {\n event_type: 'handshake',\n data: parsedData,\n };\n this.emit('handshake', handshakeEvent);\n } else if (event.event === 'stop') {\n this.emit('stop');\n }\n } catch (error: any) {\n this.emit('error', new Error(`Failed to parse SSE event data: ${error}`));\n }\n }\n\n /**\n * Starts checking for missed heartbeats\n */\n private startHeartbeatCheck(): void {\n this.stopHeartbeatCheck();\n\n this.heartbeatCheckTimer = setInterval(() => {\n const timeSinceLastHeartbeat = Date.now() - this.lastHeartbeat;\n const maxAllowedTime = HEARTBEAT_INTERVAL * MAX_MISSED_HEARTBEATS;\n\n if (timeSinceLastHeartbeat > maxAllowedTime) {\n this.emit('heartbeat_timeout');\n this.reconnect();\n }\n }, HEARTBEAT_INTERVAL);\n }\n\n /**\n * Stops heartbeat checking\n */\n private stopHeartbeatCheck(): void {\n if (this.heartbeatCheckTimer) {\n clearInterval(this.heartbeatCheckTimer);\n this.heartbeatCheckTimer = undefined;\n }\n }\n\n /**\n * Schedules a reconnection attempt\n */\n private scheduleReconnect(): void {\n if (this.reconnectTimer || this.isShutdown) {\n return;\n }\n\n this.emit('reconnecting');\n\n this.reconnectTimer = setTimeout(() => {\n this.reconnectTimer = undefined;\n this.reconnect();\n }, 1000); // Wait 1 second before reconnecting\n }\n\n /**\n * Reconnects to the SSE endpoint\n */\n private reconnect(): void {\n this.disconnect(true);\n this.connectAndListen().catch(error => {\n this.emit('error', error);\n });\n }\n\n /**\n * Disconnects from the SSE endpoint\n */\n private disconnect(stopReconnect: boolean = true): void {\n if (this.abortController) {\n this.abortController.abort();\n this.abortController = undefined;\n }\n\n this.stopHeartbeatCheck();\n\n if (stopReconnect && this.reconnectTimer) {\n clearTimeout(this.reconnectTimer);\n this.reconnectTimer = undefined;\n }\n }\n\n /**\n * Updates the function metadata (params, name) and reconnects\n */\n updateMetadata(params: RolloutParam[], name: string): void {\n this.params = params;\n this.name = name;\n\n // Reconnect to send updated metadata\n this.reconnect();\n }\n\n /**\n * Shuts down the SSE client gracefully\n */\n shutdown(): void {\n this.isShutdown = true;\n this.disconnect(true);\n this.emit('shutdown');\n this.removeAllListeners();\n }\n}\n\n/**\n * Creates an SSE client (does not auto-connect)\n * Call client.connect() after registering event listeners\n */\nexport function createSSEClient(options: SSEClientOptions): SSEClient {\n return new SSEClient(options);\n}\n","//#region src/tracing.ts\n/**\n* Tracing levels to conditionally disable tracing.\n*\n* OFF - No tracing is sent.\n* META_ONLY - Only metadata is sent (e.g. tokens, costs, etc.).\n* ALL - All data is sent.\n*/\nlet TracingLevel = /* @__PURE__ */ function(TracingLevel$1) {\n\tTracingLevel$1[\"OFF\"] = \"off\";\n\tTracingLevel$1[\"META_ONLY\"] = \"meta_only\";\n\tTracingLevel$1[\"ALL\"] = \"all\";\n\treturn TracingLevel$1;\n}({});\n\n//#endregion\n//#region src/worker-protocol.ts\n/**\n* Message prefix for protocol messages in stdout\n*/\nconst WORKER_MESSAGE_PREFIX = \"__LMNR_WORKER__:\";\n\n//#endregion\nexport { TracingLevel, WORKER_MESSAGE_PREFIX };\n//# sourceMappingURL=index.mjs.map","import pino, { Level } from 'pino';\nimport { PinoPretty } from 'pino-pretty';\n\nexport function initializeLogger(options?: { colorize?: boolean; level?: Level }) {\n const colorize = options?.colorize ?? true;\n const level =\n options?.level ??\n (process.env.LMNR_LOG_LEVEL?.toLowerCase()?.trim() as Level) ??\n 'info';\n\n return pino(\n {\n level,\n },\n PinoPretty({\n colorize,\n minimumLevel: level,\n }),\n );\n}\n","import { WORKER_MESSAGE_PREFIX, WorkerConfig, WorkerMessage } from '@lmnr-ai/types';\nimport { ChildProcess, spawn } from 'child_process';\nimport * as readline from 'readline';\n\nimport { initializeLogger } from '../utils';\n\nconst logger = initializeLogger();\n\nexport interface ExecuteOptions {\n command: string;\n args: string[];\n config: WorkerConfig;\n}\n\n/**\n * Executes a subprocess and handles the worker protocol.\n * This is a pure process.spawn wrapper with protocol handling.\n */\nexport async function executeSubprocess(options: ExecuteOptions): Promise<any> {\n return new Promise((resolve, reject) => {\n const { command, args, config } = options;\n\n // Spawn the worker process\n const child: ChildProcess = spawn(command, args, {\n stdio: ['pipe', 'pipe', 'pipe'],\n });\n\n let result: any = undefined;\n let hasError = false;\n\n // Set up readline interface for stdout\n const rl = readline.createInterface({\n input: child.stdout!,\n crlfDelay: Infinity,\n });\n\n // Handle messages from worker\n rl.on('line', (line: string) => {\n // Check if this is a worker protocol message or user output\n if (line.startsWith(WORKER_MESSAGE_PREFIX)) {\n // Parse worker protocol message\n try {\n const messageJson = line.substring(WORKER_MESSAGE_PREFIX.length);\n const message: WorkerMessage = JSON.parse(messageJson);\n\n switch (message.type) {\n // wrapped in a block for const not to be hoisted\n case 'log': {\n // Forward log messages through pino logger\n logger[message.level](message.message);\n break;\n }\n case 'result':\n result = message.data;\n break;\n\n case 'error':\n hasError = true;\n logger.error(`Worker error: ${message.error}`);\n if (message.stack) {\n logger.error(message.stack);\n }\n break;\n }\n } catch {\n // If we can't parse a prefixed message, log it as an error\n logger.error(`Failed to parse worker protocol message: ${line}`);\n }\n } else {\n // This is user output from console.log - pass it through transparently\n console.log(line);\n }\n });\n\n // Pass through stderr for user's console.error\n child.stderr!.on('data', (data: Buffer) => {\n // Write directly to stderr to preserve user's error output\n process.stderr.write(data);\n });\n\n // Handle process exit\n child.on('exit', (code: number | null, signal: string | null) => {\n if (signal) {\n reject(new Error(`Worker terminated by signal: ${signal}`));\n } else if (code === 0) {\n resolve(result);\n } else {\n if (!hasError) {\n logger.error(`Worker exited with code ${code}`);\n }\n reject(new Error(`Worker exited with code ${code}`));\n }\n });\n\n // Handle spawn errors\n child.on('error', (error: Error) => {\n reject(new Error(`Failed to spawn worker: ${error.message}`));\n });\n\n // Send configuration to worker via stdin\n child.stdin?.write(JSON.stringify(config) + '\\n');\n child.stdin?.end();\n });\n}\n\n/**\n * Track and kill the currently running subprocess\n */\nexport class SubprocessManager {\n private currentProcess: ChildProcess | null = null;\n\n /**\n * Execute a subprocess and track it\n */\n async execute(options: ExecuteOptions): Promise<any> {\n const { command, args, config } = options;\n\n // Spawn the worker process\n const child: ChildProcess = spawn(command, args, {\n stdio: ['pipe', 'pipe', 'pipe'],\n });\n\n this.currentProcess = child;\n\n return new Promise((resolve, reject) => {\n let result: any = undefined;\n let hasError = false;\n\n // Set up readline interface for stdout\n const rl = readline.createInterface({\n input: child.stdout!,\n crlfDelay: Infinity,\n });\n\n // Handle messages from worker\n rl.on('line', (line: string) => {\n // Check if this is a worker protocol message or user output\n if (line.startsWith(WORKER_MESSAGE_PREFIX)) {\n // Parse worker protocol message\n try {\n const messageJson = line.substring(WORKER_MESSAGE_PREFIX.length);\n const message: WorkerMessage = JSON.parse(messageJson);\n\n switch (message.type) {\n // wrapped in a block for const not to be hoisted\n case 'log': {\n // Forward log messages through pino logger\n logger[message.level](message.message);\n break;\n }\n case 'result':\n result = message.data;\n break;\n\n case 'error':\n hasError = true;\n logger.error(`Worker error: ${message.error}`);\n if (message.stack) {\n logger.error(message.stack);\n }\n break;\n }\n } catch {\n logger.error(`Failed to parse worker protocol message: ${line}`);\n }\n } else {\n // This is user output from console.log - pass it through transparently\n console.log(line);\n }\n });\n\n // Pass through stderr for user's console.error\n child.stderr!.on('data', (data: Buffer) => {\n process.stderr.write(data);\n });\n\n // Handle process exit\n child.on('exit', (code: number | null, signal: string | null) => {\n if (this.currentProcess?.pid === child.pid) {\n this.currentProcess = null;\n }\n\n if (signal) {\n reject(new Error(`Worker terminated by signal: ${signal}`));\n } else if (code === 0) {\n resolve(result);\n } else {\n if (!hasError) {\n logger.error(`Worker exited with code ${code}`);\n }\n reject(new Error(`Worker exited with code ${code}`));\n }\n });\n\n // Handle spawn errors\n child.on('error', (error: Error) => {\n this.currentProcess = null;\n reject(new Error(`Failed to spawn worker: ${error.message}`));\n });\n\n // Send configuration to worker via stdin\n child.stdin?.write(JSON.stringify(config) + '\\n');\n child.stdin?.end();\n });\n }\n\n /**\n * Kill the currently running subprocess\n */\n kill(): void {\n if (this.currentProcess) {\n const processToKill = this.currentProcess;\n this.currentProcess.kill('SIGTERM');\n\n // Fallback to SIGKILL after 5 seconds\n setTimeout(() => {\n // exitCode is null if the process is still running\n if (processToKill && processToKill.exitCode === null) {\n logger.warn('Child process did not terminate, using SIGKILL');\n processToKill.kill('SIGKILL');\n }\n }, 5000);\n }\n }\n\n /**\n * Check if a subprocess is currently running\n */\n isRunning(): boolean {\n return this.currentProcess !== null;\n }\n}\n","import * as path from 'path';\n\nexport interface WorkerCommand {\n command: string;\n args: string[];\n}\n\n/**\n * Default workers mapped by file extension\n */\nconst DEFAULT_WORKERS: Record<string, WorkerCommand> = {\n '.ts': {\n command: 'node',\n args: [], // Will be resolved dynamically\n },\n '.cts': {\n command: 'node',\n args: [], // Will be resolved dynamically\n },\n '.mts': {\n command: 'node',\n args: [], // Will be resolved dynamically\n },\n '.tsx': {\n command: 'node',\n args: [], // Will be resolved dynamically\n },\n '.jsx': {\n command: 'node',\n args: [], // Will be resolved dynamically\n },\n '.js': {\n command: 'node',\n args: [], // Will be resolved dynamically\n },\n '.mjs': {\n command: 'node',\n args: [], // Will be resolved dynamically\n },\n '.cjs': {\n command: 'node',\n args: [], // Will be resolved dynamically\n },\n '.py': {\n command: 'python3',\n args: ['-m', 'lmnr.cli.worker'],\n },\n};\n\n/**\n * Get the worker command for a given file path or module.\n * Resolves the TypeScript worker dynamically from @lmnr-ai/lmnr package.\n */\nexport function getWorkerCommand(\n filePath?: string,\n options?: { pythonModule?: string },\n): WorkerCommand {\n // If Python module mode, always use Python worker\n if (options?.pythonModule) {\n return {\n command: 'python3',\n args: ['-m', 'lmnr.cli.worker'],\n };\n }\n\n // Otherwise determine by file extension\n if (!filePath) {\n throw new Error('Either filePath or pythonModule must be provided');\n }\n\n const ext = path.extname(filePath);\n\n if (!DEFAULT_WORKERS[ext]) {\n throw new Error(\n `Unsupported file extension: ${ext}. ` +\n `Supported extensions: ${Object.keys(DEFAULT_WORKERS).join(', ')}`,\n );\n }\n\n const worker = DEFAULT_WORKERS[ext];\n\n // For TypeScript/JavaScript files, resolve the worker from @lmnr-ai/lmnr\n if (['.ts', '.tsx', '.js', '.mjs', '.cjs', '.mts', '.cts', '.jsx'].includes(ext)) {\n try {\n // Try to resolve the worker from @lmnr-ai/lmnr package\n const workerPath = require.resolve('@lmnr-ai/lmnr/dist/cli/worker/index.cjs');\n return {\n command: worker.command,\n args: [workerPath],\n };\n } catch (error) {\n throw new Error(\n 'Failed to resolve TypeScript/JavaScript worker from @lmnr-ai/lmnr package. ' +\n 'Make sure @lmnr-ai/lmnr is installed. ' +\n `Error: ${error instanceof Error ? error.message : String(error)}`,\n );\n }\n }\n\n return worker;\n}\n\n/**\n * Get a custom worker command with overrides.\n * Allows users to specify custom commands via CLI flags.\n */\nexport function getCustomWorkerCommand(\n command: string,\n args: string[],\n): WorkerCommand {\n return { command, args };\n}\n","import { LaminarClient } from '@lmnr-ai/client';\nimport {\n type CachedSpan,\n type RolloutHandshakeEvent,\n type RolloutParam,\n type RolloutRunEvent,\n type WorkerConfig,\n} from '@lmnr-ai/types';\nimport chokidar from 'chokidar';\nimport * as path from 'path';\nimport { v4 as uuidv4 } from 'uuid';\n\nimport { startCacheServer } from '../cache-server';\nimport { createSSEClient, SSEClient } from '../sse-client';\nimport { SubprocessManager } from '../subprocess/executor';\nimport { initializeLogger } from '../utils';\nimport { getWorkerCommand } from '../worker-registry';\n\ninterface FunctionMetadata {\n name: string; // The span name from observe({ name: '...' })\n exportName: string; // The actual export/variable name\n params: RolloutParam[];\n}\n\nconst logger = initializeLogger();\n\n// Extensions that use TypeScript/JavaScript build and runtime discovery\nconst TS_JS_EXTENSIONS = [\n '.ts',\n '.tsx',\n '.js',\n '.mjs',\n '.cjs',\n '.jsx',\n '.mts',\n '.cts',\n];\n\n// All extensions that support metadata discovery\nconst EXTENSIONS_TO_DISCOVER_METADATA = [...TS_JS_EXTENSIONS, '.py'];\n\nexport interface DevOptions {\n projectApiKey?: string;\n baseUrl?: string;\n port?: number;\n grpcPort?: number;\n function?: string;\n frontendPort?: number;\n externalPackages?: string[];\n dynamicImportsToSkip?: string[];\n command?: string;\n commandArgs?: string[];\n pythonModule?: string; // Python module path (e.g., 'src.myfile')\n}\n\ninterface DiscoveredMetadata {\n functionName: string;\n params: RolloutParam[];\n}\n\n/**\n * Discovers function metadata for TypeScript and JavaScript files by:\n * 1. Extracting TypeScript metadata (params with types from source - TS only)\n * 2. Building and loading the module with esbuild\n * 3. Selecting the appropriate function\n * 4. Matching metadata by span name\n *\n * For JavaScript files, TypeScript metadata extraction fails gracefully, but runtime\n * parameter extraction via regex still works (param names without types).\n */\nconst discoverTypeScriptMetadata = async (\n filePath: string,\n options: { function?: string; externalPackages?: string[]; dynamicImportsToSkip?: string[] },\n): Promise<DiscoveredMetadata> => {\n /* eslint-disable @typescript-eslint/no-require-imports */\n // Use dynamic require to prevent bundler from trying to resolve at build time\n const lmnrPackage = '@lmnr-ai/lmnr';\n const { extractRolloutFunctions } = require(`${lmnrPackage}/dist/cli/worker/ts-parser.cjs`);\n const {\n buildFile,\n loadModule,\n selectRolloutFunction,\n } = require(`${lmnrPackage}/dist/cli/worker/build.cjs`);\n /* eslint-enable @typescript-eslint/no-require-imports */\n\n // Extract TypeScript metadata\n let paramsMetadata: Map<string, FunctionMetadata> | undefined;\n try {\n paramsMetadata = extractRolloutFunctions(filePath);\n logger.debug(`Extracted TypeScript metadata for ${paramsMetadata?.size} functions`);\n } catch (error) {\n logger.warn(\n 'Failed to extract TypeScript metadata, falling back to runtime parsing: ' +\n (error instanceof Error ? error.message : String(error)),\n );\n }\n\n // Build and load the module\n const moduleText = await buildFile(filePath, {\n externalPackages: options.externalPackages,\n dynamicImportsToSkip: options.dynamicImportsToSkip,\n });\n loadModule({\n filename: filePath,\n moduleText,\n });\n\n // Select the appropriate function\n const selectedFunction = selectRolloutFunction(options.function);\n\n // If we have TypeScript metadata, match by span name and enrich params\n if (paramsMetadata) {\n logger.debug(`Available TS metadata keys: ${Array.from(paramsMetadata.keys()).join(', ')}`);\n logger.debug(\n `Looking for span name: ${selectedFunction.name} ` +\n `(runtime key: ${selectedFunction.exportName})`,\n );\n\n // Search for metadata by span name\n let foundMetadata: FunctionMetadata | null = null;\n for (const [exportName, metadata] of paramsMetadata.entries()) {\n logger.debug(\n `Checking ${exportName}: span name = ${metadata.name}, export name = ${exportName}`,\n );\n if (metadata.name === selectedFunction.name) {\n foundMetadata = metadata;\n logger.debug(`Match. Export name: ${exportName}, span name: ${metadata.name}`);\n break;\n }\n }\n\n if (foundMetadata) {\n selectedFunction.params = foundMetadata.params;\n logger.debug(`Using TypeScript metadata for span: ${selectedFunction.name}`);\n } else {\n logger.info(`No TypeScript metadata found for span name: ${selectedFunction.name}`);\n }\n }\n\n return {\n functionName: selectedFunction.name,\n params: selectedFunction.params || [],\n };\n};\n\n/**\n * Helper to execute subprocess commands\n */\nconst execCommand = async (\n command: string,\n args: string[],\n): Promise<{ stdout: string; stderr: string }> => new Promise((resolve, reject) => {\n // eslint-disable-next-line @typescript-eslint/no-require-imports\n const { spawn } = require('child_process');\n const child = spawn(command, args);\n let stdout = '';\n let stderr = '';\n\n child.stdout.on('data', (data: Buffer) => {\n stdout += data.toString();\n });\n child.stderr.on('data', (data: Buffer) => {\n stderr += data.toString();\n });\n\n child.on('close', (code: number | null) => {\n if (code === 0) {\n resolve({ stdout, stderr });\n } else {\n reject(new Error(`Command failed with code ${code}: ${stderr}`));\n }\n });\n\n child.on('error', (error: Error) => {\n reject(error);\n });\n});\n\n/**\n * Discovers function metadata for Python files/modules by calling the lmnr Python CLI\n */\nconst discoverPythonMetadata = async (\n filePathOrModule: string,\n options: DevOptions,\n): Promise<DiscoveredMetadata> => {\n logger.debug(`Discovering Python metadata for ${filePathOrModule}`);\n const args = ['discover'];\n\n // Determine if we're using a file path or module\n if (options.pythonModule) {\n // Module mode: lmnr discover --module src.myfile\n args.push('--module', options.pythonModule);\n } else {\n // Script mode: lmnr discover --file src/myfile.py\n args.push('--file', filePathOrModule);\n }\n\n // Add optional function name\n if (options.function) {\n args.push('--function', options.function);\n }\n\n try {\n // Execute: lmnr discover --file <path> | --module <module> [--function <name>]\n const result = await execCommand('lmnr', args);\n const response = JSON.parse(result.stdout);\n\n // Response format: { \"name\": \"...\", \"params\": [...] }\n return {\n functionName: response.name,\n params: response.params || [],\n };\n } catch (error) {\n const errorMessage = error instanceof Error ? error.message : String(error);\n logger.error(`Failed to discover Python metadata: ${errorMessage}`);\n if (errorMessage.toLowerCase().includes('command not found') ||\n errorMessage.includes('spawn lmnr ENOENT')) {\n logger.info(\n \"HINT: Make sure latest version of `lmnr` python package is installed. \" +\n \"`pip install --upgrade lmnr`, or if you are running this command from a virtual \" +\n \"environment, make sure to activate it. For `uv` users, rerun the command with `uv run`, \" +\n `e.g. \"uv run npx lmnr-cli dev ${filePathOrModule}\"`,\n );\n process.exit(1);\n }\n // Fallback\n const defaultName = options.pythonModule\n ? options.pythonModule.split('.').pop() || 'main'\n : path.basename(filePathOrModule, '.py');\n return {\n functionName: options.function || defaultName,\n params: [],\n };\n }\n};\n\n/**\n * Generic metadata discovery dispatcher that routes to language-specific implementations\n */\nconst discoverFunctionMetadata = async (\n filePathOrModule: string,\n options: DevOptions,\n): Promise<DiscoveredMetadata> => {\n // If pythonModule is set, we're in Python module mode\n if (options.pythonModule) {\n return await discoverPythonMetadata(filePathOrModule, options);\n }\n\n // Otherwise check file extension\n const ext = path.extname(filePathOrModule);\n\n // TypeScript and JavaScript files use the same build/load/select process\n // For JS files, TypeScript metadata extraction will fail, but runtime param extraction works\n if (TS_JS_EXTENSIONS.includes(ext)) {\n return await discoverTypeScriptMetadata(filePathOrModule, options);\n }\n\n if (ext === '.py') {\n return await discoverPythonMetadata(filePathOrModule, options);\n }\n\n // Fallback for unsupported file types\n logger.warn(`No metadata discovery available for ${ext} files`);\n return {\n functionName: options.function || path.basename(filePathOrModule, ext),\n params: [],\n };\n};\n\nfunction newUUID(): string {\n if (typeof crypto !== 'undefined' && typeof crypto.randomUUID === 'function') {\n return crypto.randomUUID();\n }\n return uuidv4();\n}\n\nfunction getFrontendUrl(baseUrl?: string, frontendPort?: number): string {\n let url = baseUrl ?? 'https://api.lmnr.ai';\n if (url === 'https://api.lmnr.ai') {\n url = 'https://www.laminar.sh';\n }\n url = url.replace(/\\/$/, '');\n\n if (/localhost|127\\.0\\.0\\.1/.test(url)) {\n const port = frontendPort ?? url.match(/:\\d{1,5}$/g)?.[0]?.slice(1) ?? 5667;\n url = url.replace(/:\\d{1,5}$/g, '');\n return `${url}:${port}`;\n }\n\n return url;\n}\n\n/**\n * Parses request arguments, attempting JSON parse for strings\n */\nconst tryParseArg = (arg: unknown) => {\n if (typeof arg === 'string') {\n try {\n // eslint-disable-next-line @typescript-eslint/no-unsafe-return\n return JSON.parse(arg);\n } catch {\n return arg;\n }\n }\n return arg;\n};\n\n/**\n * Handles a run event from the backend\n */\nconst handleRunEvent = async (\n event: RolloutRunEvent,\n sessionId: string,\n filePathOrModule: string,\n client: LaminarClient,\n cacheServerPort: number,\n cache: Map<string, CachedSpan>,\n setMetadata: (metadata: any) => void,\n options: DevOptions,\n subprocessManager: SubprocessManager,\n): Promise<void> => {\n logger.debug('Received run event');\n\n const { trace_id, path_to_count, args: rawArgs, overrides } = event.data;\n\n const parsedArgs = Array.isArray(rawArgs)\n ? rawArgs.map(tryParseArg)\n : (Object.fromEntries(\n Object.entries(rawArgs).map(([key, value]) => [key, tryParseArg(value)]),\n ) as Record<string, any>);\n\n cache.clear();\n setMetadata({\n pathToCount: {},\n overrides: overrides,\n });\n\n try {\n // Check if we should populate cache from a previous trace\n if (!trace_id || trace_id.trim() === '') {\n logger.info('No spans in cache, starting fresh');\n } else {\n // Query spans from the backend to populate cache\n const paths = Object.keys(path_to_count || {});\n if (paths.length === 0) {\n logger.info('No spans to cache, starting fresh');\n } else {\n const query = `\n SELECT name, input, output, attributes, path\n FROM spans\n WHERE trace_id = {traceId:UUID}\n AND path IN {paths:String[]}\n ORDER BY start_time ASC\n `;\n\n logger.debug(`Querying spans from trace ${trace_id}...`);\n const spans = await client.sql.query(query, {\n traceId: trace_id,\n paths: paths,\n });\n logger.debug(`Received ${spans.length} spans from backend`);\n\n // Group spans by path and filter to first N per path\n const spansByPath: Record<string, any[]> = {};\n for (const span of spans) {\n const path = span.path as string;\n if (!spansByPath[path]) {\n spansByPath[path] = [];\n }\n spansByPath[path].push(span);\n }\n\n for (const [path, pathSpans] of Object.entries(spansByPath)) {\n const maxCount = path_to_count?.[path] || 0;\n const spansToCache = pathSpans.slice(0, maxCount);\n\n spansToCache.forEach((span, index) => {\n // Parse JSON fields\n let parsedInput = span.input;\n let parsedOutput = span.output;\n let parsedAttributes = span.attributes;\n\n try {\n parsedInput =\n typeof span.input === 'string' ? JSON.parse(span.input) : span.input;\n } catch {\n // Keep as string\n }\n\n try {\n parsedOutput =\n typeof span.output === 'string' ? span.output : JSON.stringify(span.output);\n } catch {\n parsedOutput = String(span.output);\n }\n\n try {\n parsedAttributes =\n typeof span.attributes === 'string'\n ? JSON.parse(span.attributes)\n : span.attributes;\n } catch {\n parsedAttributes = {};\n }\n\n const cachedSpan: CachedSpan = {\n name: span.name,\n input: parsedInput,\n output: parsedOutput,\n attributes: parsedAttributes,\n };\n\n const cacheKey = `${index}:${path}`;\n cache.set(cacheKey, cachedSpan);\n });\n\n logger.info(`Cached ${spansToCache.length} spans for path: ${path}`);\n }\n\n // Store metadata in cache server\n setMetadata({\n pathToCount: path_to_count || {},\n overrides,\n });\n }\n }\n\n // Parse baseUrl similar to how evaluations does it\n const baseUrl = options.baseUrl ?? process.env.LMNR_BASE_URL ?? 'https://api.lmnr.ai';\n const httpPort =\n options.port ??\n (baseUrl.match(/:\\d{1,5}$/g)\n ? parseInt(baseUrl.match(/:\\d{1,5}$/g)![0].slice(1))\n : 443);\n const grpcPort = options.grpcPort ?? 8443;\n\n // Prepare environment variables for child process\n const env: Record<string, string> = {\n LMNR_ROLLOUT_SESSION_ID: sessionId,\n LMNR_ROLLOUT_STATE_SERVER_ADDRESS: `http://localhost:${cacheServerPort}`,\n };\n\n // Prepare worker configuration\n const workerConfig: WorkerConfig = {\n filePath: options.pythonModule ? undefined : filePathOrModule,\n modulePath: options.pythonModule,\n functionName: options.function,\n args: parsedArgs,\n env,\n cacheServerPort,\n baseUrl,\n projectApiKey: options.projectApiKey,\n httpPort,\n grpcPort,\n externalPackages: options.externalPackages,\n dynamicImportsToSkip: options.dynamicImportsToSkip,\n };\n\n // Get worker command\n const workerCommand = options.command\n ? { command: options.command, args: options.commandArgs ?? [] }\n : getWorkerCommand(options.pythonModule ? undefined : filePathOrModule, options);\n\n try {\n await client.rolloutSessions.setStatus({\n sessionId,\n status: 'RUNNING',\n });\n } catch (error: any) {\n logger.error(\n `Error setting rollout session status: ${error instanceof Error ? error.message : error}`,\n );\n }\n\n // Execute the rollout function in subprocess\n await subprocessManager.execute({\n command: workerCommand.command,\n args: workerCommand.args,\n config: workerConfig,\n });\n\n try {\n await client.rolloutSessions.setStatus({\n sessionId,\n status: 'FINISHED',\n });\n } catch (error: any) {\n logger.error(\n `Error setting rollout session status: ${error instanceof Error ? error.message : error}`,\n );\n }\n } catch (error: any) {\n logger.error(`Error handling run event: ${error instanceof Error ? error.message : error}`);\n if (error instanceof Error && error.stack) {\n logger.error(error.stack);\n }\n try {\n await client.rolloutSessions.setStatus({\n sessionId,\n status: 'FINISHED',\n });\n } catch (error: any) {\n logger.error(\n `Error setting rollout session status: ${error instanceof Error ? error.message : error}`,\n );\n }\n }\n};\n\n/**\n * Main dev command handler\n */\nexport async function runDev(filePath?: string, options: DevOptions = {}): Promise<void> {\n // Determine the actual path/module to use\n const isPythonModule = !!options.pythonModule;\n const filePathOrModule = filePath || options.pythonModule!;\n\n // Generate session ID\n const sessionId = newUUID();\n\n // Initialize Laminar client\n const client = new LaminarClient({\n baseUrl: options.baseUrl,\n projectApiKey: options.projectApiKey,\n port: options.port,\n });\n\n // Start cache server\n logger.debug('Starting cache server...');\n const { port: cacheServerPort, server: cacheServer, cache, setMetadata } =\n await startCacheServer();\n logger.debug(`Cache server started on port ${cacheServerPort}`);\n\n // Create subprocess manager\n const subprocessManager = new SubprocessManager();\n\n // Get function metadata (name and params)\n let functionName = options.function;\n let params: RolloutParam[] = [];\n\n try {\n // Check if we should discover metadata\n const shouldDiscover =\n isPythonModule ||\n (filePath && EXTENSIONS_TO_DISCOVER_METADATA.includes(path.extname(filePath)));\n\n if (shouldDiscover) {\n logger.debug('Discovering rollout functions...');\n const metadata = await discoverFunctionMetadata(filePathOrModule, options);\n functionName = metadata.functionName;\n params = metadata.params;\n\n logger.info(`Serving function: ${functionName}`);\n logger.debug(`Function parameters: ${JSON.stringify(params, null, 2)}`);\n } else if (filePath) {\n // Unsupported file type\n functionName = options.function || path.basename(filePath, path.extname(filePath));\n logger.warn(`Metadata discovery not available for ${path.extname(filePath)} files`);\n }\n } catch (error) {\n logger.error(\n 'Failed to discover rollout functions: ' +\n (error instanceof Error ? error.message : String(error)),\n );\n cacheServer.close();\n throw error;\n }\n\n // Setup file watcher for hot reload\n logger.debug('Setting up file watcher...');\n const watcher = chokidar.watch('.', {\n ignored: (path: string) => {\n const ignoredDirs = [\n 'node_modules',\n '.git',\n 'dist',\n 'build',\n '.next',\n 'coverage',\n '.turbo',\n 'tmp',\n 'temp',\n 'venv',\n '.venv',\n 'virtualenv',\n '.virtualenv',\n '__pycache__',\n '.pytest_cache',\n '.ruff_cache',\n '.mypy_cache',\n '.cache',\n '.DS_Store',\n ];\n\n const pathSegments = path.split(/[/\\\\]/);\n if (pathSegments.some((segment) => ignoredDirs.includes(segment))) {\n return true;\n }\n\n if (path.endsWith('.log') || path.endsWith('.map')) {\n return true;\n }\n\n return false;\n },\n persistent: true,\n ignoreInitial: true,\n awaitWriteFinish: {\n stabilityThreshold: 100,\n pollInterval: 100,\n },\n });\n\n // Create SSE client\n logger.debug('Setting up SSE client...');\n let sseClient: SSEClient | null = null;\n\n try {\n sseClient = createSSEClient({\n client,\n sessionId,\n params: params,\n name: functionName ?? '',\n });\n\n // Register all event listeners BEFORE connecting\n sseClient.on('heartbeat', () => {\n logger.debug('Heartbeat received');\n });\n\n sseClient.on('run', (event: RolloutRunEvent) => {\n if (subprocessManager.isRunning()) {\n logger.warn('Rollout is already running, skipping new run');\n return;\n }\n\n handleRunEvent(\n event,\n sessionId,\n filePathOrModule,\n client,\n cacheServerPort,\n cache,\n setMetadata,\n options,\n subprocessManager,\n ).catch((error) => {\n logger.error(\n 'Unhandled error in run event handler: ' +\n (error instanceof Error ? error.message : String(error)),\n );\n });\n });\n\n sseClient.on('handshake', (event: RolloutHandshakeEvent) => {\n const projectId = event.data.project_id;\n const sessionId = event.data.session_id;\n const frontendUrl = getFrontendUrl(options.baseUrl, options.frontendPort);\n logger.info(\n `View your session at ${frontendUrl}/project/${projectId}/rollout-sessions/${sessionId}`,\n );\n });\n\n sseClient.on('error', (error: Error) => {\n logger.warn(`Error connecting to backend: ${error.message}`);\n });\n\n sseClient.on('reconnecting', () => {\n logger.info('Reconnecting to backend...');\n });\n\n sseClient.on('heartbeat_timeout', () => {\n logger.debug('Heartbeat timeout, reconnecting...');\n });\n\n sseClient.on('stop', () => {\n logger.debug('Cancelling current run...');\n subprocessManager.kill();\n logger.info('Current run cancelled');\n });\n\n // Setup file change handler for hot reload\n watcher.on('change', (changedPath: string) => {\n logger.info(`File changed: ${changedPath}, reloading...`);\n\n // Cancel running subprocess\n if (subprocessManager.isRunning()) {\n logger.warn('Cancelling current run due to file change');\n subprocessManager.kill();\n }\n\n // Re-discover function metadata for supported file types\n if (\n isPythonModule ||\n (filePath &&\n EXTENSIONS_TO_DISCOVER_METADATA.includes(path.extname(filePath)))\n ) {\n discoverFunctionMetadata(filePathOrModule, options)\n .then((metadata) => {\n logger.debug(`Updated function metadata: ${metadata.functionName}`);\n logger.debug(`Updated parameters: ${JSON.stringify(metadata.params, null, 2)}`);\n\n // Update the SSE client with new metadata\n if (sseClient) {\n sseClient.updateMetadata(metadata.params, metadata.functionName);\n logger.debug('Notified backend of metadata changes');\n }\n })\n .catch((error: any) => {\n logger.error(\n 'Failed to update function metadata: ' +\n (error instanceof Error ? error.message : String(error)),\n );\n });\n }\n });\n\n // Handle graceful shutdown\n const shutdown = () => {\n logger.debug('Shutting down...');\n\n // Close file watcher\n logger.debug('Closing file watcher...');\n watcher\n .close()\n .catch((error: any) => {\n logger.error(\n `Failed to close file watcher: ${error instanceof Error ? error.message : error}`,\n );\n });\n\n // Kill any running subprocess\n subprocessManager.kill();\n\n // Delete the rollout session\n logger.debug('Deleting rollout session...');\n client.rolloutSessions\n .delete({ sessionId })\n .then(() => {\n if (sseClient) {\n sseClient.shutdown();\n }\n\n cacheServer.close(() => {\n logger.debug('Cache server closed');\n });\n process.exit(0);\n })\n .catch((error: any) => {\n logger.warn(\n `Failed to delete rollout session: ${error instanceof Error ? error.message : error}`,\n );\n process.exit(1);\n });\n };\n\n process.on('SIGINT', shutdown);\n process.on('SIGTERM', shutdown);\n\n // Keep stdin open to prevent process from exiting\n process.stdin.resume();\n\n // Connect to backend and start listening\n logger.debug('Connecting to backend...');\n await sseClient.connectAndListen();\n } catch (error) {\n logger.error(\n 'Failed to start dev command: ' + (error instanceof Error ? error.message : String(error)),\n );\n\n // Try to delete the rollout session before exiting\n try {\n await client.rolloutSessions.delete({ sessionId });\n } catch {\n // Ignore delete errors during error cleanup\n }\n\n await watcher.close();\n cacheServer.close(() => {\n process.exit(1);\n });\n }\n}\n","#!/usr/bin/env node\n\nimport { Command } from 'commander';\n\nimport { version } from '../package.json';\nimport { runDev } from './commands/dev';\n\nasync function main() {\n const program = new Command();\n\n program\n .name('lmnr-cli')\n .description('CLI for Laminar AI rollout debugging')\n .version(version, '-v, --version', 'display version number');\n\n program\n .command('dev')\n .description('Start a rollout debugging session')\n .argument(\n '[file]',\n 'Path to file containing the agent function(s). Either `file` or `-m` must be provided.',\n )\n .option(\n '-m, --python-module <module>',\n 'Python module path (e.g., src.myfile). Either `file` or `-m` must be provided.',\n )\n .option(\n '--function <name>',\n 'Specific function to serve (if multiple rollout functions found)',\n )\n .option(\n '--project-api-key <key>',\n 'Project API key. If not provided, reads from LMNR_PROJECT_API_KEY env variable',\n )\n .option(\n '--base-url <url>',\n 'Base URL for the Laminar API. Defaults to https://api.lmnr.ai or LMNR_BASE_URL env variable',\n )\n .option('--port <port>', 'Port for the Laminar API. Defaults to 443', (val) =>\n parseInt(val, 10),\n )\n .option(\n '--grpc-port <port>',\n 'Port for the Laminar gRPC backend. Defaults to 8443',\n (val) => parseInt(val, 10),\n )\n .option(\n '--frontend-port <port>',\n 'Port for the Laminar frontend. Defaults to 5667',\n (val) => parseInt(val, 10),\n )\n .option(\n '--external-packages <packages...>',\n '[ADVANCED] List of packages to pass as external to esbuild. This will not link ' +\n 'the packages directly into the dev file, but will instead require them at runtime. ' +\n 'Read more: https://esbuild.github.io/api/#external',\n )\n .option(\n '--dynamic-imports-to-skip <modules...>',\n '[ADVANCED] List of module names to skip when encountered as dynamic imports. ' +\n 'These dynamic imports will resolve to an empty module to prevent build failures. ' +\n 'This is meant to skip the imports that are not used in the rollout itself.',\n )\n .option(\n '--command <command>',\n '[ADVANCED] Custom command to run the worker (e.g., python3, node)',\n )\n .option(\n '--command-args <args...>',\n '[ADVANCED] Arguments for the custom command',\n )\n .action(async (file: string | undefined, options) => {\n // Validation: must have either file or python-module, but not both\n if (!file && !options.pythonModule) {\n console.error('Error: Must provide either a file path or --python-module (-m) flag');\n process.exit(1);\n }\n if (file && options.pythonModule) {\n console.error('Error: Cannot specify both file path and --python-module (-m) flag');\n process.exit(1);\n }\n\n await runDev(file, options);\n })\n .addHelpText(\n 'after',\n `\nExamples:\n $ lmnr-cli dev agent.ts # TypeScript file\n $ lmnr-cli dev agent.py # Python file (script mode)\n $ lmnr-cli dev -m src.agent # Python module (module mode)\n $ lmnr-cli dev agent.ts --function myAgent # Specific function\n`,\n );\n\n await program.parseAsync();\n}\n\nmain().catch((err) => {\n console.error(err instanceof Error ? err.message : err);\n process.exit(1);\n});\n"],"x_google_ignoreList":[1,2],"mappings":"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"}
1
+ {"version":3,"file":"index.cjs","names":["path","crypto","initializeLogger","newUUID","logger$1","logger","metadata: CacheMetadata","path","response: CacheServerResponse","EventEmitter","error: any","runEvent: RolloutRunEvent","handshakeEvent: RolloutHandshakeEvent","logger","child: ChildProcess","result: any","message: WorkerMessage","config","DEFAULT_WORKERS: Record<string, WorkerCommand>","extractRolloutFunctions: any","buildFile: any","loadModule: any","selectRolloutFunction: any","error: any","paramsMetadata: Map<string, FunctionMetadata> | undefined","foundMetadata: FunctionMetadata | null","spawn","spansByPath: Record<string, any[]>","path","cachedSpan: CachedSpan","env: Record<string, string>","workerConfig: WorkerConfig","error","params: RolloutParam[]","sseClient: SSEClient | null","sessionId","Command","version"],"sources":["../package.json","../../../node_modules/.pnpm/dotenv@17.2.3/node_modules/dotenv/package.json","../../../node_modules/.pnpm/dotenv@17.2.3/node_modules/dotenv/lib/main.js","../../client/dist/index.mjs","../src/cache-server.ts","../src/sse-client.ts","../../types/dist/index.mjs","../src/utils.ts","../src/subprocess/executor.ts","../src/worker-registry.ts","../src/commands/dev.ts","../src/index.ts"],"sourcesContent":["","","const fs = require('fs')\nconst path = require('path')\nconst os = require('os')\nconst crypto = require('crypto')\nconst packageJson = require('../package.json')\n\nconst version = packageJson.version\n\n// Array of tips to display randomly\nconst TIPS = [\n '🔐 encrypt with Dotenvx: https://dotenvx.com',\n '🔐 prevent committing .env to code: https://dotenvx.com/precommit',\n '🔐 prevent building .env in docker: https://dotenvx.com/prebuild',\n '📡 add observability to secrets: https://dotenvx.com/ops',\n '👥 sync secrets across teammates & machines: https://dotenvx.com/ops',\n '🗂️ backup and recover secrets: https://dotenvx.com/ops',\n '✅ audit secrets and track compliance: https://dotenvx.com/ops',\n '🔄 add secrets lifecycle management: https://dotenvx.com/ops',\n '🔑 add access controls to secrets: https://dotenvx.com/ops',\n '🛠️ run anywhere with `dotenvx run -- yourcommand`',\n '⚙️ specify custom .env file path with { path: \\'/custom/path/.env\\' }',\n '⚙️ enable debug logging with { debug: true }',\n '⚙️ override existing env vars with { override: true }',\n '⚙️ suppress all logs with { quiet: true }',\n '⚙️ write to custom object with { processEnv: myObject }',\n '⚙️ load multiple .env files with { path: [\\'.env.local\\', \\'.env\\'] }'\n]\n\n// Get a random tip from the tips array\nfunction _getRandomTip () {\n return TIPS[Math.floor(Math.random() * TIPS.length)]\n}\n\nfunction parseBoolean (value) {\n if (typeof value === 'string') {\n return !['false', '0', 'no', 'off', ''].includes(value.toLowerCase())\n }\n return Boolean(value)\n}\n\nfunction supportsAnsi () {\n return process.stdout.isTTY // && process.env.TERM !== 'dumb'\n}\n\nfunction dim (text) {\n return supportsAnsi() ? `\\x1b[2m${text}\\x1b[0m` : text\n}\n\nconst LINE = /(?:^|^)\\s*(?:export\\s+)?([\\w.-]+)(?:\\s*=\\s*?|:\\s+?)(\\s*'(?:\\\\'|[^'])*'|\\s*\"(?:\\\\\"|[^\"])*\"|\\s*`(?:\\\\`|[^`])*`|[^#\\r\\n]+)?\\s*(?:#.*)?(?:$|$)/mg\n\n// Parse src into an Object\nfunction parse (src) {\n const obj = {}\n\n // Convert buffer to string\n let lines = src.toString()\n\n // Convert line breaks to same format\n lines = lines.replace(/\\r\\n?/mg, '\\n')\n\n let match\n while ((match = LINE.exec(lines)) != null) {\n const key = match[1]\n\n // Default undefined or null to empty string\n let value = (match[2] || '')\n\n // Remove whitespace\n value = value.trim()\n\n // Check if double quoted\n const maybeQuote = value[0]\n\n // Remove surrounding quotes\n value = value.replace(/^(['\"`])([\\s\\S]*)\\1$/mg, '$2')\n\n // Expand newlines if double quoted\n if (maybeQuote === '\"') {\n value = value.replace(/\\\\n/g, '\\n')\n value = value.replace(/\\\\r/g, '\\r')\n }\n\n // Add to object\n obj[key] = value\n }\n\n return obj\n}\n\nfunction _parseVault (options) {\n options = options || {}\n\n const vaultPath = _vaultPath(options)\n options.path = vaultPath // parse .env.vault\n const result = DotenvModule.configDotenv(options)\n if (!result.parsed) {\n const err = new Error(`MISSING_DATA: Cannot parse ${vaultPath} for an unknown reason`)\n err.code = 'MISSING_DATA'\n throw err\n }\n\n // handle scenario for comma separated keys - for use with key rotation\n // example: DOTENV_KEY=\"dotenv://:key_1234@dotenvx.com/vault/.env.vault?environment=prod,dotenv://:key_7890@dotenvx.com/vault/.env.vault?environment=prod\"\n const keys = _dotenvKey(options).split(',')\n const length = keys.length\n\n let decrypted\n for (let i = 0; i < length; i++) {\n try {\n // Get full key\n const key = keys[i].trim()\n\n // Get instructions for decrypt\n const attrs = _instructions(result, key)\n\n // Decrypt\n decrypted = DotenvModule.decrypt(attrs.ciphertext, attrs.key)\n\n break\n } catch (error) {\n // last key\n if (i + 1 >= length) {\n throw error\n }\n // try next key\n }\n }\n\n // Parse decrypted .env string\n return DotenvModule.parse(decrypted)\n}\n\nfunction _warn (message) {\n console.error(`[dotenv@${version}][WARN] ${message}`)\n}\n\nfunction _debug (message) {\n console.log(`[dotenv@${version}][DEBUG] ${message}`)\n}\n\nfunction _log (message) {\n console.log(`[dotenv@${version}] ${message}`)\n}\n\nfunction _dotenvKey (options) {\n // prioritize developer directly setting options.DOTENV_KEY\n if (options && options.DOTENV_KEY && options.DOTENV_KEY.length > 0) {\n return options.DOTENV_KEY\n }\n\n // secondary infra already contains a DOTENV_KEY environment variable\n if (process.env.DOTENV_KEY && process.env.DOTENV_KEY.length > 0) {\n return process.env.DOTENV_KEY\n }\n\n // fallback to empty string\n return ''\n}\n\nfunction _instructions (result, dotenvKey) {\n // Parse DOTENV_KEY. Format is a URI\n let uri\n try {\n uri = new URL(dotenvKey)\n } catch (error) {\n if (error.code === 'ERR_INVALID_URL') {\n const err = new Error('INVALID_DOTENV_KEY: Wrong format. Must be in valid uri format like dotenv://:key_1234@dotenvx.com/vault/.env.vault?environment=development')\n err.code = 'INVALID_DOTENV_KEY'\n throw err\n }\n\n throw error\n }\n\n // Get decrypt key\n const key = uri.password\n if (!key) {\n const err = new Error('INVALID_DOTENV_KEY: Missing key part')\n err.code = 'INVALID_DOTENV_KEY'\n throw err\n }\n\n // Get environment\n const environment = uri.searchParams.get('environment')\n if (!environment) {\n const err = new Error('INVALID_DOTENV_KEY: Missing environment part')\n err.code = 'INVALID_DOTENV_KEY'\n throw err\n }\n\n // Get ciphertext payload\n const environmentKey = `DOTENV_VAULT_${environment.toUpperCase()}`\n const ciphertext = result.parsed[environmentKey] // DOTENV_VAULT_PRODUCTION\n if (!ciphertext) {\n const err = new Error(`NOT_FOUND_DOTENV_ENVIRONMENT: Cannot locate environment ${environmentKey} in your .env.vault file.`)\n err.code = 'NOT_FOUND_DOTENV_ENVIRONMENT'\n throw err\n }\n\n return { ciphertext, key }\n}\n\nfunction _vaultPath (options) {\n let possibleVaultPath = null\n\n if (options && options.path && options.path.length > 0) {\n if (Array.isArray(options.path)) {\n for (const filepath of options.path) {\n if (fs.existsSync(filepath)) {\n possibleVaultPath = filepath.endsWith('.vault') ? filepath : `${filepath}.vault`\n }\n }\n } else {\n possibleVaultPath = options.path.endsWith('.vault') ? options.path : `${options.path}.vault`\n }\n } else {\n possibleVaultPath = path.resolve(process.cwd(), '.env.vault')\n }\n\n if (fs.existsSync(possibleVaultPath)) {\n return possibleVaultPath\n }\n\n return null\n}\n\nfunction _resolveHome (envPath) {\n return envPath[0] === '~' ? path.join(os.homedir(), envPath.slice(1)) : envPath\n}\n\nfunction _configVault (options) {\n const debug = parseBoolean(process.env.DOTENV_CONFIG_DEBUG || (options && options.debug))\n const quiet = parseBoolean(process.env.DOTENV_CONFIG_QUIET || (options && options.quiet))\n\n if (debug || !quiet) {\n _log('Loading env from encrypted .env.vault')\n }\n\n const parsed = DotenvModule._parseVault(options)\n\n let processEnv = process.env\n if (options && options.processEnv != null) {\n processEnv = options.processEnv\n }\n\n DotenvModule.populate(processEnv, parsed, options)\n\n return { parsed }\n}\n\nfunction configDotenv (options) {\n const dotenvPath = path.resolve(process.cwd(), '.env')\n let encoding = 'utf8'\n let processEnv = process.env\n if (options && options.processEnv != null) {\n processEnv = options.processEnv\n }\n let debug = parseBoolean(processEnv.DOTENV_CONFIG_DEBUG || (options && options.debug))\n let quiet = parseBoolean(processEnv.DOTENV_CONFIG_QUIET || (options && options.quiet))\n\n if (options && options.encoding) {\n encoding = options.encoding\n } else {\n if (debug) {\n _debug('No encoding is specified. UTF-8 is used by default')\n }\n }\n\n let optionPaths = [dotenvPath] // default, look for .env\n if (options && options.path) {\n if (!Array.isArray(options.path)) {\n optionPaths = [_resolveHome(options.path)]\n } else {\n optionPaths = [] // reset default\n for (const filepath of options.path) {\n optionPaths.push(_resolveHome(filepath))\n }\n }\n }\n\n // Build the parsed data in a temporary object (because we need to return it). Once we have the final\n // parsed data, we will combine it with process.env (or options.processEnv if provided).\n let lastError\n const parsedAll = {}\n for (const path of optionPaths) {\n try {\n // Specifying an encoding returns a string instead of a buffer\n const parsed = DotenvModule.parse(fs.readFileSync(path, { encoding }))\n\n DotenvModule.populate(parsedAll, parsed, options)\n } catch (e) {\n if (debug) {\n _debug(`Failed to load ${path} ${e.message}`)\n }\n lastError = e\n }\n }\n\n const populated = DotenvModule.populate(processEnv, parsedAll, options)\n\n // handle user settings DOTENV_CONFIG_ options inside .env file(s)\n debug = parseBoolean(processEnv.DOTENV_CONFIG_DEBUG || debug)\n quiet = parseBoolean(processEnv.DOTENV_CONFIG_QUIET || quiet)\n\n if (debug || !quiet) {\n const keysCount = Object.keys(populated).length\n const shortPaths = []\n for (const filePath of optionPaths) {\n try {\n const relative = path.relative(process.cwd(), filePath)\n shortPaths.push(relative)\n } catch (e) {\n if (debug) {\n _debug(`Failed to load ${filePath} ${e.message}`)\n }\n lastError = e\n }\n }\n\n _log(`injecting env (${keysCount}) from ${shortPaths.join(',')} ${dim(`-- tip: ${_getRandomTip()}`)}`)\n }\n\n if (lastError) {\n return { parsed: parsedAll, error: lastError }\n } else {\n return { parsed: parsedAll }\n }\n}\n\n// Populates process.env from .env file\nfunction config (options) {\n // fallback to original dotenv if DOTENV_KEY is not set\n if (_dotenvKey(options).length === 0) {\n return DotenvModule.configDotenv(options)\n }\n\n const vaultPath = _vaultPath(options)\n\n // dotenvKey exists but .env.vault file does not exist\n if (!vaultPath) {\n _warn(`You set DOTENV_KEY but you are missing a .env.vault file at ${vaultPath}. Did you forget to build it?`)\n\n return DotenvModule.configDotenv(options)\n }\n\n return DotenvModule._configVault(options)\n}\n\nfunction decrypt (encrypted, keyStr) {\n const key = Buffer.from(keyStr.slice(-64), 'hex')\n let ciphertext = Buffer.from(encrypted, 'base64')\n\n const nonce = ciphertext.subarray(0, 12)\n const authTag = ciphertext.subarray(-16)\n ciphertext = ciphertext.subarray(12, -16)\n\n try {\n const aesgcm = crypto.createDecipheriv('aes-256-gcm', key, nonce)\n aesgcm.setAuthTag(authTag)\n return `${aesgcm.update(ciphertext)}${aesgcm.final()}`\n } catch (error) {\n const isRange = error instanceof RangeError\n const invalidKeyLength = error.message === 'Invalid key length'\n const decryptionFailed = error.message === 'Unsupported state or unable to authenticate data'\n\n if (isRange || invalidKeyLength) {\n const err = new Error('INVALID_DOTENV_KEY: It must be 64 characters long (or more)')\n err.code = 'INVALID_DOTENV_KEY'\n throw err\n } else if (decryptionFailed) {\n const err = new Error('DECRYPTION_FAILED: Please check your DOTENV_KEY')\n err.code = 'DECRYPTION_FAILED'\n throw err\n } else {\n throw error\n }\n }\n}\n\n// Populate process.env with parsed values\nfunction populate (processEnv, parsed, options = {}) {\n const debug = Boolean(options && options.debug)\n const override = Boolean(options && options.override)\n const populated = {}\n\n if (typeof parsed !== 'object') {\n const err = new Error('OBJECT_REQUIRED: Please check the processEnv argument being passed to populate')\n err.code = 'OBJECT_REQUIRED'\n throw err\n }\n\n // Set process.env\n for (const key of Object.keys(parsed)) {\n if (Object.prototype.hasOwnProperty.call(processEnv, key)) {\n if (override === true) {\n processEnv[key] = parsed[key]\n populated[key] = parsed[key]\n }\n\n if (debug) {\n if (override === true) {\n _debug(`\"${key}\" is already defined and WAS overwritten`)\n } else {\n _debug(`\"${key}\" is already defined and was NOT overwritten`)\n }\n }\n } else {\n processEnv[key] = parsed[key]\n populated[key] = parsed[key]\n }\n }\n\n return populated\n}\n\nconst DotenvModule = {\n configDotenv,\n _configVault,\n _parseVault,\n config,\n decrypt,\n parse,\n populate\n}\n\nmodule.exports.configDotenv = DotenvModule.configDotenv\nmodule.exports._configVault = DotenvModule._configVault\nmodule.exports._parseVault = DotenvModule._parseVault\nmodule.exports.config = DotenvModule.config\nmodule.exports.decrypt = DotenvModule.decrypt\nmodule.exports.parse = DotenvModule.parse\nmodule.exports.populate = DotenvModule.populate\n\nmodule.exports = DotenvModule\n","import { config } from \"dotenv\";\nimport * as path from \"path\";\nimport pino from \"pino\";\nimport { PinoPretty } from \"pino-pretty\";\nimport { v4 } from \"uuid\";\n\n//#region package.json\nvar version = \"0.8.3\";\n\n//#endregion\n//#region src/version.ts\nfunction getLangVersion() {\n\tif (typeof process !== \"undefined\" && process.versions && process.versions.node) return `node-${process.versions.node}`;\n\tif (typeof navigator !== \"undefined\" && navigator.userAgent) return `browser-${navigator.userAgent}`;\n\treturn null;\n}\n\n//#endregion\n//#region src/resources/index.ts\nvar BaseResource = class {\n\tconstructor(baseHttpUrl, projectApiKey) {\n\t\tthis.baseHttpUrl = baseHttpUrl;\n\t\tthis.projectApiKey = projectApiKey;\n\t}\n\theaders() {\n\t\treturn {\n\t\t\tAuthorization: `Bearer ${this.projectApiKey}`,\n\t\t\t\"Content-Type\": \"application/json\",\n\t\t\tAccept: \"application/json\"\n\t\t};\n\t}\n\tasync handleError(response) {\n\t\tconst errorMsg = await response.text();\n\t\tthrow new Error(`${response.status} ${errorMsg}`);\n\t}\n};\n\n//#endregion\n//#region src/resources/browser-events.ts\nvar BrowserEventsResource = class extends BaseResource {\n\tconstructor(baseHttpUrl, projectApiKey) {\n\t\tsuper(baseHttpUrl, projectApiKey);\n\t}\n\tasync send({ sessionId, traceId, events }) {\n\t\tconst payload = {\n\t\t\tsessionId,\n\t\t\ttraceId,\n\t\t\tevents,\n\t\t\tsource: getLangVersion() ?? \"javascript\",\n\t\t\tsdkVersion: version\n\t\t};\n\t\tconst jsonString = JSON.stringify(payload);\n\t\tconst compressedStream = new Blob([jsonString], { type: \"application/json\" }).stream().pipeThrough(new CompressionStream(\"gzip\"));\n\t\tconst compressedData = await new Response(compressedStream).arrayBuffer();\n\t\tconst response = await fetch(this.baseHttpUrl + \"/v1/browser-sessions/events\", {\n\t\t\tmethod: \"POST\",\n\t\t\theaders: {\n\t\t\t\t...this.headers(),\n\t\t\t\t\"Content-Encoding\": \"gzip\"\n\t\t\t},\n\t\t\tbody: compressedData\n\t\t});\n\t\tif (!response.ok) await this.handleError(response);\n\t}\n};\n\n//#endregion\n//#region src/utils.ts\nfunction initializeLogger(options) {\n\tconst colorize = options?.colorize ?? true;\n\tconst level = options?.level ?? process.env.LMNR_LOG_LEVEL?.toLowerCase()?.trim() ?? \"info\";\n\treturn pino({ level }, PinoPretty({\n\t\tcolorize,\n\t\tminimumLevel: level\n\t}));\n}\nconst logger$2 = initializeLogger();\nconst isStringUUID = (id) => /^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/.test(id);\nconst newUUID = () => {\n\tif (typeof crypto !== \"undefined\" && typeof crypto.randomUUID === \"function\") return crypto.randomUUID();\n\telse return v4();\n};\nconst otelSpanIdToUUID = (spanId) => {\n\tlet id = spanId.toLowerCase();\n\tif (id.startsWith(\"0x\")) id = id.slice(2);\n\tif (id.length !== 16) logger$2.warn(`Span ID ${spanId} is not 16 hex chars long. This is not a valid OpenTelemetry span ID.`);\n\tif (!/^[0-9a-f]+$/.test(id)) {\n\t\tlogger$2.error(`Span ID ${spanId} is not a valid hex string. Generating a random UUID instead.`);\n\t\treturn newUUID();\n\t}\n\treturn id.padStart(32, \"0\").replace(/^([0-9a-f]{8})([0-9a-f]{4})([0-9a-f]{4})([0-9a-f]{4})([0-9a-f]{12})$/, \"$1-$2-$3-$4-$5\");\n};\nconst otelTraceIdToUUID = (traceId) => {\n\tlet id = traceId.toLowerCase();\n\tif (id.startsWith(\"0x\")) id = id.slice(2);\n\tif (id.length !== 32) logger$2.warn(`Trace ID ${traceId} is not 32 hex chars long. This is not a valid OpenTelemetry trace ID.`);\n\tif (!/^[0-9a-f]+$/.test(id)) {\n\t\tlogger$2.error(`Trace ID ${traceId} is not a valid hex string. Generating a random UUID instead.`);\n\t\treturn newUUID();\n\t}\n\treturn id.replace(/^([0-9a-f]{8})([0-9a-f]{4})([0-9a-f]{4})([0-9a-f]{4})([0-9a-f]{12})$/, \"$1-$2-$3-$4-$5\");\n};\nconst slicePayload = (value, length) => {\n\tif (value === null || value === void 0) return value;\n\tconst str = JSON.stringify(value);\n\tif (str.length <= length) return value;\n\treturn str.slice(0, length) + \"...\";\n};\nconst loadEnv = (options) => {\n\tconst nodeEnv = process.env.NODE_ENV || \"development\";\n\tconst envDir = process.cwd();\n\tconst envFiles = [\n\t\t\".env\",\n\t\t\".env.local\",\n\t\t`.env.${nodeEnv}`,\n\t\t`.env.${nodeEnv}.local`\n\t];\n\tconst logLevel = process.env.LMNR_LOG_LEVEL ?? \"info\";\n\tconst verbose = [\"debug\", \"trace\"].includes(logLevel.trim().toLowerCase());\n\tconst quiet = options?.quiet ?? !verbose;\n\tconfig({\n\t\tpath: options?.paths ?? envFiles.map((envFile) => path.resolve(envDir, envFile)),\n\t\tquiet\n\t});\n};\n\n//#endregion\n//#region src/resources/datasets.ts\nconst logger$1 = initializeLogger();\nconst DEFAULT_DATASET_PULL_LIMIT = 100;\nconst DEFAULT_DATASET_PUSH_BATCH_SIZE = 100;\nvar DatasetsResource = class extends BaseResource {\n\tconstructor(baseHttpUrl, projectApiKey) {\n\t\tsuper(baseHttpUrl, projectApiKey);\n\t}\n\t/**\n\t* List all datasets.\n\t*\n\t* @returns {Promise<Dataset[]>} Array of datasets\n\t*/\n\tasync listDatasets() {\n\t\tconst response = await fetch(this.baseHttpUrl + \"/v1/datasets\", {\n\t\t\tmethod: \"GET\",\n\t\t\theaders: this.headers()\n\t\t});\n\t\tif (!response.ok) await this.handleError(response);\n\t\treturn response.json();\n\t}\n\t/**\n\t* Get a dataset by name.\n\t*\n\t* @param {string} name - Name of the dataset\n\t* @returns {Promise<Dataset[]>} Array of datasets with matching name\n\t*/\n\tasync getDatasetByName(name) {\n\t\tconst params = new URLSearchParams({ name });\n\t\tconst response = await fetch(this.baseHttpUrl + `/v1/datasets?${params.toString()}`, {\n\t\t\tmethod: \"GET\",\n\t\t\theaders: this.headers()\n\t\t});\n\t\tif (!response.ok) await this.handleError(response);\n\t\treturn response.json();\n\t}\n\t/**\n\t* Push datapoints to a dataset.\n\t*\n\t* @param {Object} options - Push options\n\t* @param {Datapoint<D, T>[]} options.points - Datapoints to push\n\t* @param {string} [options.name] - Name of the dataset (either name or id must be provided)\n\t* @param {StringUUID} [options.id] - ID of the dataset (either name or id must be provided)\n\t* @param {number} [options.batchSize] - Batch size for pushing (default: 100)\n\t* @param {boolean} [options.createDataset] - Whether to create the dataset if it doesn't exist\n\t* @returns {Promise<PushDatapointsResponse | undefined>}\n\t*/\n\tasync push({ points, name, id, batchSize = DEFAULT_DATASET_PUSH_BATCH_SIZE, createDataset = false }) {\n\t\tif (!name && !id) throw new Error(\"Either name or id must be provided\");\n\t\tif (name && id) throw new Error(\"Only one of name or id must be provided\");\n\t\tif (createDataset && !name) throw new Error(\"Name must be provided when creating a new dataset\");\n\t\tconst identifier = name ? { name } : { datasetId: id };\n\t\tconst totalBatches = Math.ceil(points.length / batchSize);\n\t\tlet response;\n\t\tfor (let i = 0; i < points.length; i += batchSize) {\n\t\t\tconst batchNum = Math.floor(i / batchSize) + 1;\n\t\t\tlogger$1.debug(`Pushing batch ${batchNum} of ${totalBatches}`);\n\t\t\tconst batch = points.slice(i, i + batchSize);\n\t\t\tconst fetchResponse = await fetch(this.baseHttpUrl + \"/v1/datasets/datapoints\", {\n\t\t\t\tmethod: \"POST\",\n\t\t\t\theaders: this.headers(),\n\t\t\t\tbody: JSON.stringify({\n\t\t\t\t\t...identifier,\n\t\t\t\t\tdatapoints: batch.map((point) => ({\n\t\t\t\t\t\tdata: point.data,\n\t\t\t\t\t\ttarget: point.target ?? {},\n\t\t\t\t\t\tmetadata: point.metadata ?? {}\n\t\t\t\t\t})),\n\t\t\t\t\tcreateDataset\n\t\t\t\t})\n\t\t\t});\n\t\t\tif (fetchResponse.status !== 200 && fetchResponse.status !== 201) await this.handleError(fetchResponse);\n\t\t\tresponse = await fetchResponse.json();\n\t\t}\n\t\treturn response;\n\t}\n\t/**\n\t* Pull datapoints from a dataset.\n\t*\n\t* @param {Object} options - Pull options\n\t* @param {string} [options.name] - Name of the dataset (either name or id must be provided)\n\t* @param {StringUUID} [options.id] - ID of the dataset (either name or id must be provided)\n\t* @param {number} [options.limit] - Maximum number of datapoints to return (default: 100)\n\t* @param {number} [options.offset] - Offset for pagination (default: 0)\n\t* @returns {Promise<GetDatapointsResponse<D, T>>}\n\t*/\n\tasync pull({ name, id, limit = DEFAULT_DATASET_PULL_LIMIT, offset = 0 }) {\n\t\tif (!name && !id) throw new Error(\"Either name or id must be provided\");\n\t\tif (name && id) throw new Error(\"Only one of name or id must be provided\");\n\t\tconst paramsObj = {\n\t\t\toffset: offset.toString(),\n\t\t\tlimit: limit.toString()\n\t\t};\n\t\tif (name) paramsObj.name = name;\n\t\telse paramsObj.datasetId = id;\n\t\tconst params = new URLSearchParams(paramsObj);\n\t\tconst response = await fetch(this.baseHttpUrl + `/v1/datasets/datapoints?${params.toString()}`, {\n\t\t\tmethod: \"GET\",\n\t\t\theaders: this.headers()\n\t\t});\n\t\tif (!response.ok) await this.handleError(response);\n\t\treturn response.json();\n\t}\n};\n\n//#endregion\n//#region src/resources/evals.ts\nconst logger = initializeLogger();\nconst INITIAL_EVALUATION_DATAPOINT_MAX_DATA_LENGTH = 16e6;\nvar EvalsResource = class extends BaseResource {\n\tconstructor(baseHttpUrl, projectApiKey) {\n\t\tsuper(baseHttpUrl, projectApiKey);\n\t}\n\t/**\n\t* Initialize an evaluation.\n\t*\n\t* @param {string} name - Name of the evaluation\n\t* @param {string} groupName - Group name of the evaluation\n\t* @param {Record<string, any>} metadata - Optional metadata\n\t* @returns {Promise<InitEvaluationResponse>} Response from the evaluation initialization\n\t*/\n\tasync init(name, groupName, metadata) {\n\t\tconst response = await fetch(this.baseHttpUrl + \"/v1/evals\", {\n\t\t\tmethod: \"POST\",\n\t\t\theaders: this.headers(),\n\t\t\tbody: JSON.stringify({\n\t\t\t\tname: name ?? null,\n\t\t\t\tgroupName: groupName ?? null,\n\t\t\t\tmetadata: metadata ?? null\n\t\t\t})\n\t\t});\n\t\tif (!response.ok) await this.handleError(response);\n\t\treturn response.json();\n\t}\n\t/**\n\t* Create a new evaluation and return its ID.\n\t*\n\t* @param {string} [name] - Optional name of the evaluation\n\t* @param {string} [groupName] - An identifier to group evaluations\n\t* @param {Record<string, any>} [metadata] - Optional metadata\n\t* @returns {Promise<StringUUID>} The evaluation ID\n\t*/\n\tasync create(args) {\n\t\treturn (await this.init(args?.name, args?.groupName, args?.metadata)).id;\n\t}\n\t/**\n\t* Create a new evaluation and return its ID.\n\t* @deprecated use `create` instead.\n\t*/\n\tasync createEvaluation(name, groupName, metadata) {\n\t\treturn (await this.init(name, groupName, metadata)).id;\n\t}\n\t/**\n\t* Create a datapoint for an evaluation.\n\t*\n\t* @param {Object} options - Create datapoint options\n\t* @param {string} options.evalId - The evaluation ID\n\t* @param {D} options.data - The input data for the executor\n\t* @param {T} [options.target] - The target/expected output for evaluators\n\t* @param {Record<string, any>} [options.metadata] - Optional metadata\n\t* @param {number} [options.index] - Optional index of the datapoint\n\t* @param {string} [options.traceId] - Optional trace ID\n\t* @returns {Promise<StringUUID>} The datapoint ID\n\t*/\n\tasync createDatapoint({ evalId, data, target, metadata, index, traceId }) {\n\t\tconst datapointId = newUUID();\n\t\tconst partialDatapoint = {\n\t\t\tid: datapointId,\n\t\t\tdata,\n\t\t\ttarget,\n\t\t\tindex: index ?? 0,\n\t\t\ttraceId: traceId ?? newUUID(),\n\t\t\texecutorSpanId: newUUID(),\n\t\t\tmetadata\n\t\t};\n\t\tawait this.saveDatapoints({\n\t\t\tevalId,\n\t\t\tdatapoints: [partialDatapoint]\n\t\t});\n\t\treturn datapointId;\n\t}\n\t/**\n\t* Update a datapoint with evaluation results.\n\t*\n\t* @param {Object} options - Update datapoint options\n\t* @param {string} options.evalId - The evaluation ID\n\t* @param {string} options.datapointId - The datapoint ID\n\t* @param {Record<string, number>} options.scores - The scores\n\t* @param {O} [options.executorOutput] - The executor output\n\t* @returns {Promise<void>}\n\t*/\n\tasync updateDatapoint({ evalId, datapointId, scores, executorOutput }) {\n\t\tconst response = await fetch(this.baseHttpUrl + `/v1/evals/${evalId}/datapoints/${datapointId}`, {\n\t\t\tmethod: \"POST\",\n\t\t\theaders: this.headers(),\n\t\t\tbody: JSON.stringify({\n\t\t\t\texecutorOutput,\n\t\t\t\tscores\n\t\t\t})\n\t\t});\n\t\tif (!response.ok) await this.handleError(response);\n\t}\n\t/**\n\t* Save evaluation datapoints.\n\t*\n\t* @param {Object} options - Save datapoints options\n\t* @param {string} options.evalId - ID of the evaluation\n\t* @param {EvaluationDatapoint<D, T, O>[]} options.datapoints - Datapoint to add\n\t* @param {string} [options.groupName] - Group name of the evaluation\n\t* @returns {Promise<void>} Response from the datapoint addition\n\t*/\n\tasync saveDatapoints({ evalId, datapoints, groupName }) {\n\t\tconst response = await fetch(this.baseHttpUrl + `/v1/evals/${evalId}/datapoints`, {\n\t\t\tmethod: \"POST\",\n\t\t\theaders: this.headers(),\n\t\t\tbody: JSON.stringify({\n\t\t\t\tpoints: datapoints.map((d) => ({\n\t\t\t\t\t...d,\n\t\t\t\t\tdata: slicePayload(d.data, INITIAL_EVALUATION_DATAPOINT_MAX_DATA_LENGTH),\n\t\t\t\t\ttarget: slicePayload(d.target, INITIAL_EVALUATION_DATAPOINT_MAX_DATA_LENGTH),\n\t\t\t\t\texecutorOutput: slicePayload(d.executorOutput, INITIAL_EVALUATION_DATAPOINT_MAX_DATA_LENGTH)\n\t\t\t\t})),\n\t\t\t\tgroupName: groupName ?? null\n\t\t\t})\n\t\t});\n\t\tif (response.status === 413) return await this.retrySaveDatapoints({\n\t\t\tevalId,\n\t\t\tdatapoints,\n\t\t\tgroupName\n\t\t});\n\t\tif (!response.ok) await this.handleError(response);\n\t}\n\t/**\n\t* Get evaluation datapoints.\n\t*\n\t* @deprecated Use `client.datasets.pull()` instead.\n\t* @param {Object} options - Get datapoints options\n\t* @param {string} options.datasetName - Name of the dataset\n\t* @param {number} options.offset - Offset at which to start the query\n\t* @param {number} options.limit - Maximum number of datapoints to return\n\t* @returns {Promise<GetDatapointsResponse>} Response from the datapoint retrieval\n\t*/\n\tasync getDatapoints({ datasetName, offset, limit }) {\n\t\tlogger.warn(\"evals.getDatapoints() is deprecated. Use client.datasets.pull() instead.\");\n\t\tconst params = new URLSearchParams({\n\t\t\tname: datasetName,\n\t\t\toffset: offset.toString(),\n\t\t\tlimit: limit.toString()\n\t\t});\n\t\tconst response = await fetch(this.baseHttpUrl + `/v1/datasets/datapoints?${params.toString()}`, {\n\t\t\tmethod: \"GET\",\n\t\t\theaders: this.headers()\n\t\t});\n\t\tif (!response.ok) await this.handleError(response);\n\t\treturn await response.json();\n\t}\n\tasync retrySaveDatapoints({ evalId, datapoints, groupName, maxRetries = 25, initialLength = INITIAL_EVALUATION_DATAPOINT_MAX_DATA_LENGTH }) {\n\t\tlet length = initialLength;\n\t\tlet lastResponse = null;\n\t\tfor (let i = 0; i < maxRetries; i++) {\n\t\t\tlogger.debug(`Retrying save datapoints... ${i + 1} of ${maxRetries}, length: ${length}`);\n\t\t\tconst response = await fetch(this.baseHttpUrl + `/v1/evals/${evalId}/datapoints`, {\n\t\t\t\tmethod: \"POST\",\n\t\t\t\theaders: this.headers(),\n\t\t\t\tbody: JSON.stringify({\n\t\t\t\t\tpoints: datapoints.map((d) => ({\n\t\t\t\t\t\t...d,\n\t\t\t\t\t\tdata: slicePayload(d.data, length),\n\t\t\t\t\t\ttarget: slicePayload(d.target, length),\n\t\t\t\t\t\texecutorOutput: slicePayload(d.executorOutput, length)\n\t\t\t\t\t})),\n\t\t\t\t\tgroupName: groupName ?? null\n\t\t\t\t})\n\t\t\t});\n\t\t\tlastResponse = response;\n\t\t\tlength = Math.floor(length / 2);\n\t\t\tif (response.status !== 413) break;\n\t\t}\n\t\tif (lastResponse && !lastResponse.ok) await this.handleError(lastResponse);\n\t}\n};\n\n//#endregion\n//#region src/resources/evaluators.ts\nvar EvaluatorScoreSourceType = /* @__PURE__ */ function(EvaluatorScoreSourceType$1) {\n\tEvaluatorScoreSourceType$1[\"Evaluator\"] = \"Evaluator\";\n\tEvaluatorScoreSourceType$1[\"Code\"] = \"Code\";\n\treturn EvaluatorScoreSourceType$1;\n}(EvaluatorScoreSourceType || {});\n/**\n* Resource for creating evaluator scores\n*/\nvar EvaluatorsResource = class extends BaseResource {\n\tconstructor(baseHttpUrl, projectApiKey) {\n\t\tsuper(baseHttpUrl, projectApiKey);\n\t}\n\t/**\n\t* Create a score for a span or trace\n\t*\n\t* @param {ScoreOptions} options - Score creation options\n\t* @param {string} options.name - Name of the score\n\t* @param {string} [options.traceId] - The trace ID to score (will be attached to top-level span)\n\t* @param {string} [options.spanId] - The span ID to score\n\t* @param {Record<string, any>} [options.metadata] - Additional metadata\n\t* @param {number} options.score - The score value (float)\n\t* @returns {Promise<void>}\n\t*\n\t* @example\n\t* // Score by trace ID (will attach to root span)\n\t* await evaluators.score({\n\t* name: \"quality\",\n\t* traceId: \"trace-id-here\",\n\t* score: 0.95,\n\t* metadata: { model: \"gpt-4\" }\n\t* });\n\t*\n\t* @example\n\t* // Score by span ID\n\t* await evaluators.score({\n\t* name: \"relevance\",\n\t* spanId: \"span-id-here\",\n\t* score: 0.87\n\t* });\n\t*/\n\tasync score(options) {\n\t\tconst { name, metadata, score } = options;\n\t\tlet payload;\n\t\tif (\"traceId\" in options && options.traceId) {\n\t\t\tconst formattedTraceId = isStringUUID(options.traceId) ? options.traceId : otelTraceIdToUUID(options.traceId);\n\t\t\tpayload = {\n\t\t\t\tname,\n\t\t\t\tmetadata,\n\t\t\t\tscore,\n\t\t\t\tsource: EvaluatorScoreSourceType.Code,\n\t\t\t\ttraceId: formattedTraceId\n\t\t\t};\n\t\t} else if (\"spanId\" in options && options.spanId) {\n\t\t\tconst formattedSpanId = isStringUUID(options.spanId) ? options.spanId : otelSpanIdToUUID(options.spanId);\n\t\t\tpayload = {\n\t\t\t\tname,\n\t\t\t\tmetadata,\n\t\t\t\tscore,\n\t\t\t\tsource: EvaluatorScoreSourceType.Code,\n\t\t\t\tspanId: formattedSpanId\n\t\t\t};\n\t\t} else throw new Error(\"Either 'traceId' or 'spanId' must be provided.\");\n\t\tconst response = await fetch(this.baseHttpUrl + \"/v1/evaluators/score\", {\n\t\t\tmethod: \"POST\",\n\t\t\theaders: this.headers(),\n\t\t\tbody: JSON.stringify(payload)\n\t\t});\n\t\tif (!response.ok) await this.handleError(response);\n\t}\n};\n\n//#endregion\n//#region src/resources/rollout-sessions.ts\nvar RolloutSessionsResource = class extends BaseResource {\n\tconstructor(baseHttpUrl, projectApiKey) {\n\t\tsuper(baseHttpUrl, projectApiKey);\n\t}\n\t/**\n\t* Connects to the SSE stream for rollout debugging sessions\n\t* Returns the Response object for streaming SSE events\n\t*/\n\tasync connect({ sessionId, name, params, signal }) {\n\t\tconst response = await fetch(`${this.baseHttpUrl}/v1/rollouts/${sessionId}`, {\n\t\t\tmethod: \"POST\",\n\t\t\theaders: {\n\t\t\t\t...this.headers(),\n\t\t\t\t\"Accept\": \"text/event-stream\"\n\t\t\t},\n\t\t\tbody: JSON.stringify({\n\t\t\t\tname,\n\t\t\t\tparams\n\t\t\t}),\n\t\t\tsignal\n\t\t});\n\t\tif (!response.ok) throw new Error(`SSE connection failed: ${response.status} ${response.statusText}`);\n\t\tif (!response.body) throw new Error(\"No response body\");\n\t\treturn response;\n\t}\n\tasync delete({ sessionId }) {\n\t\tconst response = await fetch(`${this.baseHttpUrl}/v1/rollouts/${sessionId}`, {\n\t\t\tmethod: \"DELETE\",\n\t\t\theaders: this.headers()\n\t\t});\n\t\tif (!response.ok) await this.handleError(response);\n\t}\n\tasync setStatus({ sessionId, status }) {\n\t\tconst response = await fetch(`${this.baseHttpUrl}/v1/rollouts/${sessionId}/status`, {\n\t\t\tmethod: \"PATCH\",\n\t\t\theaders: this.headers(),\n\t\t\tbody: JSON.stringify({ status })\n\t\t});\n\t\tif (!response.ok) await this.handleError(response);\n\t}\n\tasync sendSpanUpdate({ sessionId, span }) {\n\t\tconst response = await fetch(`${this.baseHttpUrl}/v1/rollouts/${sessionId}/update`, {\n\t\t\tmethod: \"PATCH\",\n\t\t\theaders: this.headers(),\n\t\t\tbody: JSON.stringify({\n\t\t\t\ttype: \"spanStart\",\n\t\t\t\tspanId: otelSpanIdToUUID(span.spanId),\n\t\t\t\ttraceId: otelTraceIdToUUID(span.traceId),\n\t\t\t\tparentSpanId: span.parentSpanId ? otelSpanIdToUUID(span.parentSpanId) : void 0,\n\t\t\t\tattributes: span.attributes,\n\t\t\t\tstartTime: span.startTime,\n\t\t\t\tname: span.name,\n\t\t\t\tspanType: span.spanType\n\t\t\t})\n\t\t});\n\t\tif (!response.ok) await this.handleError(response);\n\t}\n};\n\n//#endregion\n//#region src/resources/sql.ts\nvar SqlResource = class extends BaseResource {\n\tconstructor(baseHttpUrl, projectApiKey) {\n\t\tsuper(baseHttpUrl, projectApiKey);\n\t}\n\tasync query(sql, parameters = {}) {\n\t\tconst response = await fetch(`${this.baseHttpUrl}/v1/sql/query`, {\n\t\t\tmethod: \"POST\",\n\t\t\theaders: { ...this.headers() },\n\t\t\tbody: JSON.stringify({\n\t\t\t\tquery: sql,\n\t\t\t\tparameters\n\t\t\t})\n\t\t});\n\t\tif (!response.ok) await this.handleError(response);\n\t\treturn (await response.json()).data;\n\t}\n};\n\n//#endregion\n//#region src/resources/tags.ts\n/** Resource for tagging traces. */\nvar TagsResource = class extends BaseResource {\n\t/** Resource for tagging traces. */\n\tconstructor(baseHttpUrl, projectApiKey) {\n\t\tsuper(baseHttpUrl, projectApiKey);\n\t}\n\t/**\n\t* Tag a trace with a list of tags. Note that the trace must be ended before\n\t* tagging it. You may want to call `await Laminar.flush()` after the trace\n\t* that you want to tag.\n\t*\n\t* @param {string | StringUUID} trace_id - The trace id to tag.\n\t* @param {string[] | string} tags - The tag or list of tags to add to the trace.\n\t* @returns {Promise<any>} The response from the server.\n\t* @example\n\t* ```javascript\n\t* import { Laminar, observe, LaminarClient } from \"@lmnr-ai/lmnr\";\n\t* Laminar.initialize();\n\t* const client = new LaminarClient();\n\t* let traceId: StringUUID | null = null;\n\t* // Make sure this is called outside of traced context.\n\t* await observe(\n\t* {\n\t* name: \"my-trace\",\n\t* },\n\t* async () => {\n\t* traceId = await Laminar.getTraceId();\n\t* await foo();\n\t* },\n\t* );\n\t*\n\t* // or make sure the trace is ended by this point.\n\t* await Laminar.flush();\n\t* if (traceId) {\n\t* await client.tags.tag(traceId, [\"tag1\", \"tag2\"]);\n\t* }\n\t* ```\n\t*/\n\tasync tag(trace_id, tags) {\n\t\tconst traceTags = Array.isArray(tags) ? tags : [tags];\n\t\tconst formattedTraceId = isStringUUID(trace_id) ? trace_id : otelTraceIdToUUID(trace_id);\n\t\tconst url = this.baseHttpUrl + \"/v1/tag\";\n\t\tconst payload = {\n\t\t\t\"traceId\": formattedTraceId,\n\t\t\t\"names\": traceTags\n\t\t};\n\t\tconst response = await fetch(url, {\n\t\t\tmethod: \"POST\",\n\t\t\theaders: this.headers(),\n\t\t\tbody: JSON.stringify(payload)\n\t\t});\n\t\tif (!response.ok) await this.handleError(response);\n\t\treturn response.json();\n\t}\n};\n\n//#endregion\n//#region src/index.ts\nvar LaminarClient = class {\n\tconstructor({ baseUrl, projectApiKey, port } = {}) {\n\t\tloadEnv();\n\t\tthis.projectApiKey = projectApiKey ?? process.env.LMNR_PROJECT_API_KEY;\n\t\tconst httpPort = port ?? (baseUrl?.match(/:\\d{1,5}$/g) ? parseInt(baseUrl.match(/:\\d{1,5}$/g)[0].slice(1)) : 443);\n\t\tthis.baseUrl = `${(baseUrl ?? process.env.LMNR_BASE_URL)?.replace(/\\/$/, \"\").replace(/:\\d{1,5}$/g, \"\") ?? \"https://api.lmnr.ai\"}:${httpPort}`;\n\t\tthis._browserEvents = new BrowserEventsResource(this.baseUrl, this.projectApiKey);\n\t\tthis._datasets = new DatasetsResource(this.baseUrl, this.projectApiKey);\n\t\tthis._evals = new EvalsResource(this.baseUrl, this.projectApiKey);\n\t\tthis._evaluators = new EvaluatorsResource(this.baseUrl, this.projectApiKey);\n\t\tthis._rolloutSessions = new RolloutSessionsResource(this.baseUrl, this.projectApiKey);\n\t\tthis._sql = new SqlResource(this.baseUrl, this.projectApiKey);\n\t\tthis._tags = new TagsResource(this.baseUrl, this.projectApiKey);\n\t}\n\tget browserEvents() {\n\t\treturn this._browserEvents;\n\t}\n\tget datasets() {\n\t\treturn this._datasets;\n\t}\n\tget evals() {\n\t\treturn this._evals;\n\t}\n\tget evaluators() {\n\t\treturn this._evaluators;\n\t}\n\tget rolloutSessions() {\n\t\treturn this._rolloutSessions;\n\t}\n\tget sql() {\n\t\treturn this._sql;\n\t}\n\tget tags() {\n\t\treturn this._tags;\n\t}\n};\n\n//#endregion\nexport { LaminarClient };\n//# sourceMappingURL=index.mjs.map","import {\n CachedSpan,\n CacheMetadata,\n CacheServerResponse,\n} from '@lmnr-ai/types';\nimport * as http from 'http';\n\ninterface CacheServerResult {\n port: number;\n server: http.Server;\n cache: Map<string, CachedSpan>;\n setMetadata: (metadata: CacheMetadata) => void;\n}\n\nconst DEFAULT_START_PORT = 35667;\n\n/**\n * Finds an available port starting from the given port number\n */\nasync function findAvailablePort(startPort: number): Promise<number> {\n return new Promise((resolve, reject) => {\n const server = http.createServer();\n\n server.listen(startPort, () => {\n const port = (server.address() as any).port;\n server.close(() => resolve(port));\n });\n\n server.on('error', (err: any) => {\n if (err.code === 'EADDRINUSE') {\n // Port is in use, try the next one\n resolve(findAvailablePort(startPort + 1));\n } else {\n reject(err as Error);\n }\n });\n });\n}\n\n/**\n * Parses request body as JSON\n */\nfunction parseBody(req: http.IncomingMessage): Promise<any> {\n return new Promise((resolve, reject) => {\n let body = '';\n\n req.on('data', (chunk) => {\n body += chunk.toString();\n });\n\n req.on('end', () => {\n try {\n resolve(body ? JSON.parse(body) : {});\n } catch (err) {\n reject(new Error(`Invalid JSON: ${err instanceof Error ? err.message : String(err)}`));\n }\n });\n\n req.on('error', reject);\n });\n}\n\n/**\n * Starts a local cache server for storing and retrieving cached LLM responses\n * during rollout debugging sessions.\n *\n * @param startPort - Optional starting port number (defaults to 35667)\n * @returns Server information including port, server instance, cache, and metadata setter\n */\nexport async function startCacheServer(\n startPort: number = DEFAULT_START_PORT,\n): Promise<CacheServerResult> {\n const cache = new Map<string, CachedSpan>();\n let metadata: CacheMetadata = {\n pathToCount: {},\n overrides: undefined,\n };\n\n const server = http.createServer((req, res) => {\n (async () => {\n // Set CORS headers for local development\n res.setHeader('Access-Control-Allow-Origin', '*');\n res.setHeader('Access-Control-Allow-Methods', 'GET, POST, OPTIONS');\n res.setHeader('Access-Control-Allow-Headers', 'Content-Type');\n\n // Handle preflight requests\n if (req.method === 'OPTIONS') {\n res.writeHead(200);\n res.end();\n return;\n }\n\n // Health check endpoint\n if (req.method === 'GET' && req.url === '/health') {\n res.writeHead(200, { 'Content-Type': 'application/json' });\n res.end(JSON.stringify({ status: 'ok' }));\n return;\n }\n\n // Cached response endpoint\n if (req.method === 'POST' && req.url === '/cached') {\n try {\n const body = await parseBody(req);\n const { path, index } = body;\n\n if (typeof path !== 'string' || typeof index !== 'number') {\n res.writeHead(400, { 'Content-Type': 'application/json' });\n res.end(JSON.stringify(\n { error: 'Invalid request: path (string) and index (number) required' },\n ));\n return;\n }\n\n // Cache key is ${index}:${path} to handle colons in paths\n const cacheKey = `${index}:${path}`;\n const cachedSpan = cache.get(cacheKey);\n\n // Return cached span with metadata\n const response: CacheServerResponse = {\n span: cachedSpan,\n pathToCount: metadata.pathToCount,\n overrides: metadata.overrides,\n };\n\n res.writeHead(200, { 'Content-Type': 'application/json' });\n res.end(JSON.stringify(response));\n } catch (err) {\n res.writeHead(400, { 'Content-Type': 'application/json' });\n res.end(JSON.stringify(\n { error: err instanceof Error ? err.message : String(err) },\n ));\n }\n return;\n }\n\n // 404 for unknown routes\n res.writeHead(404, { 'Content-Type': 'application/json' });\n res.end(JSON.stringify({ error: 'Not found' }));\n })().catch((error) => {\n // Catch any unexpected errors and send 500 response\n if (!res.headersSent) {\n res.writeHead(500, { 'Content-Type': 'application/json' });\n res.end(JSON.stringify({\n error: error instanceof Error ? error.message : 'Internal server error',\n }));\n }\n });\n });\n\n const port = await findAvailablePort(startPort);\n\n return new Promise((resolve, reject) => {\n server.listen(port, () => {\n resolve({\n port,\n server,\n cache,\n setMetadata: (newMetadata: CacheMetadata) => {\n metadata = newMetadata;\n },\n });\n });\n\n server.on('error', reject);\n });\n}\n","import { LaminarClient } from '@lmnr-ai/client';\nimport { RolloutHandshakeEvent, RolloutParam, RolloutRunEvent } from '@lmnr-ai/types';\nimport { EventEmitter } from 'events';\nimport { createParser } from 'eventsource-parser';\n\nconst HEARTBEAT_INTERVAL = 5000; // 5 seconds\nconst MAX_MISSED_HEARTBEATS = 3; // N missed intervals before reconnect\n\nexport interface SSEClientOptions {\n client: LaminarClient;\n sessionId: string;\n params: RolloutParam[];\n name: string;\n}\n\n/**\n * SSE client for rollout debugging sessions\n * Connects to the Laminar backend and listens for run events\n */\nexport class SSEClient extends EventEmitter {\n private client: LaminarClient;\n private sessionId: string;\n private params: RolloutParam[];\n private name: string;\n private abortController?: AbortController;\n private reconnectTimer?: NodeJS.Timeout;\n private lastHeartbeat: number = Date.now();\n private heartbeatCheckTimer?: NodeJS.Timeout;\n private isShutdown: boolean = false;\n\n constructor(options: SSEClientOptions) {\n super();\n this.client = options.client;\n this.sessionId = options.sessionId;\n this.params = options.params;\n this.name = options.name;\n }\n\n /**\n * Connects to the SSE endpoint\n */\n async connectAndListen(): Promise<void> {\n if (this.isShutdown) {\n return;\n }\n\n this.abortController = new AbortController();\n this.lastHeartbeat = Date.now();\n\n try {\n const response = await this.client.rolloutSessions.connect({\n sessionId: this.sessionId,\n params: this.params,\n signal: this.abortController.signal,\n name: this.name,\n });\n\n this.emit('connected');\n this.startHeartbeatCheck();\n\n // Parse SSE stream\n await this.parseSSEStream(response.body!);\n } catch (error: any) {\n if (error.name === 'AbortError') {\n // Connection was aborted intentionally\n return;\n }\n\n this.emit('error', error);\n\n if (!this.isShutdown) {\n // Attempt to reconnect\n this.scheduleReconnect();\n }\n }\n }\n\n /**\n * Parses SSE stream and emits events\n */\n private async parseSSEStream(body: ReadableStream<Uint8Array>): Promise<void> {\n const reader = body.getReader();\n const decoder = new TextDecoder();\n\n // Create SSE parser with proper event handling\n const parser = createParser({\n onEvent: (event: any) => {\n this.processSSEEvent(event);\n },\n });\n\n try {\n while (true) {\n const { done, value } = await reader.read();\n\n if (done) {\n break;\n }\n\n // Feed the chunks to the parser\n const chunk = decoder.decode(value, { stream: true });\n parser.feed(chunk);\n }\n } finally {\n reader.releaseLock();\n }\n\n // Connection ended, try to reconnect if not shutdown\n if (!this.isShutdown) {\n this.scheduleReconnect();\n }\n }\n\n /**\n * Processes a parsed SSE event\n */\n private processSSEEvent(event: any): void {\n if (!event.data) {\n return;\n }\n\n try {\n // The event.event field contains the event type ('heartbeat' or 'run')\n // The event.data field contains the JSON payload\n if (event.event === 'heartbeat') {\n this.lastHeartbeat = Date.now();\n this.emit('heartbeat');\n } else if (event.event === 'run') {\n const parsedData = JSON.parse(event.data);\n const runEvent: RolloutRunEvent = {\n event_type: 'run',\n data: parsedData,\n };\n this.emit('run', runEvent);\n } else if (event.event === 'handshake') {\n const parsedData = JSON.parse(event.data);\n const handshakeEvent: RolloutHandshakeEvent = {\n event_type: 'handshake',\n data: parsedData,\n };\n this.emit('handshake', handshakeEvent);\n } else if (event.event === 'stop') {\n this.emit('stop');\n }\n } catch (error: any) {\n this.emit('error', new Error(`Failed to parse SSE event data: ${error}`));\n }\n }\n\n /**\n * Starts checking for missed heartbeats\n */\n private startHeartbeatCheck(): void {\n this.stopHeartbeatCheck();\n\n this.heartbeatCheckTimer = setInterval(() => {\n const timeSinceLastHeartbeat = Date.now() - this.lastHeartbeat;\n const maxAllowedTime = HEARTBEAT_INTERVAL * MAX_MISSED_HEARTBEATS;\n\n if (timeSinceLastHeartbeat > maxAllowedTime) {\n this.emit('heartbeat_timeout');\n this.reconnect();\n }\n }, HEARTBEAT_INTERVAL);\n }\n\n /**\n * Stops heartbeat checking\n */\n private stopHeartbeatCheck(): void {\n if (this.heartbeatCheckTimer) {\n clearInterval(this.heartbeatCheckTimer);\n this.heartbeatCheckTimer = undefined;\n }\n }\n\n /**\n * Schedules a reconnection attempt\n */\n private scheduleReconnect(): void {\n if (this.reconnectTimer || this.isShutdown) {\n return;\n }\n\n this.emit('reconnecting');\n\n this.reconnectTimer = setTimeout(() => {\n this.reconnectTimer = undefined;\n this.reconnect();\n }, 1000); // Wait 1 second before reconnecting\n }\n\n /**\n * Reconnects to the SSE endpoint\n */\n private reconnect(): void {\n this.disconnect(true);\n this.connectAndListen().catch(error => {\n this.emit('error', error);\n });\n }\n\n /**\n * Disconnects from the SSE endpoint\n */\n private disconnect(stopReconnect: boolean = true): void {\n if (this.abortController) {\n this.abortController.abort();\n this.abortController = undefined;\n }\n\n this.stopHeartbeatCheck();\n\n if (stopReconnect && this.reconnectTimer) {\n clearTimeout(this.reconnectTimer);\n this.reconnectTimer = undefined;\n }\n }\n\n /**\n * Updates the function metadata (params, name) and reconnects\n */\n updateMetadata(params: RolloutParam[], name: string): void {\n this.params = params;\n this.name = name;\n\n // Reconnect to send updated metadata\n this.reconnect();\n }\n\n /**\n * Shuts down the SSE client gracefully\n */\n shutdown(): void {\n this.isShutdown = true;\n this.disconnect(true);\n this.emit('shutdown');\n this.removeAllListeners();\n }\n}\n\n/**\n * Creates an SSE client (does not auto-connect)\n * Call client.connect() after registering event listeners\n */\nexport function createSSEClient(options: SSEClientOptions): SSEClient {\n return new SSEClient(options);\n}\n","//#region src/tracing.ts\n/**\n* Tracing levels to conditionally disable tracing.\n*\n* OFF - No tracing is sent.\n* META_ONLY - Only metadata is sent (e.g. tokens, costs, etc.).\n* ALL - All data is sent.\n*/\nlet TracingLevel = /* @__PURE__ */ function(TracingLevel$1) {\n\tTracingLevel$1[\"OFF\"] = \"off\";\n\tTracingLevel$1[\"META_ONLY\"] = \"meta_only\";\n\tTracingLevel$1[\"ALL\"] = \"all\";\n\treturn TracingLevel$1;\n}({});\n\n//#endregion\n//#region src/worker-protocol.ts\n/**\n* Message prefix for protocol messages in stdout\n*/\nconst WORKER_MESSAGE_PREFIX = \"__LMNR_WORKER__:\";\n\n//#endregion\nexport { TracingLevel, WORKER_MESSAGE_PREFIX };\n//# sourceMappingURL=index.mjs.map","import pino, { Level } from 'pino';\nimport { PinoPretty } from 'pino-pretty';\n\nexport function initializeLogger(options?: { colorize?: boolean; level?: Level }) {\n const colorize = options?.colorize ?? true;\n const level =\n options?.level ??\n (process.env.LMNR_LOG_LEVEL?.toLowerCase()?.trim() as Level) ??\n 'info';\n\n return pino(\n {\n level,\n },\n PinoPretty({\n colorize,\n minimumLevel: level,\n }),\n );\n}\n","import { WORKER_MESSAGE_PREFIX, WorkerConfig, WorkerMessage } from '@lmnr-ai/types';\nimport { ChildProcess, spawn } from 'child_process';\nimport * as readline from 'readline';\n\nimport { initializeLogger } from '../utils';\n\nconst logger = initializeLogger();\n\nexport interface ExecuteOptions {\n command: string;\n args: string[];\n config: WorkerConfig;\n}\n\n/**\n * Track and kill the currently running subprocess\n */\nexport class SubprocessManager {\n private currentProcess: ChildProcess | null = null;\n\n /**\n * Execute a subprocess and track it\n */\n async execute(options: ExecuteOptions): Promise<any> {\n const { command, args, config } = options;\n\n // Spawn the worker process\n const child: ChildProcess = spawn(command, args, {\n stdio: ['pipe', 'pipe', 'pipe'],\n });\n\n this.currentProcess = child;\n\n return new Promise((resolve, reject) => {\n let result: any = undefined;\n let hasError = false;\n\n // Set up readline interface for stdout\n const rl = readline.createInterface({\n input: child.stdout!,\n crlfDelay: Infinity,\n });\n\n // Handle messages from worker\n rl.on('line', (line: string) => {\n // Check if this is a worker protocol message or user output\n if (line.startsWith(WORKER_MESSAGE_PREFIX)) {\n // Parse worker protocol message\n try {\n const messageJson = line.substring(WORKER_MESSAGE_PREFIX.length);\n const message: WorkerMessage = JSON.parse(messageJson);\n\n switch (message.type) {\n // wrapped in a block for const not to be hoisted\n case 'log': {\n // Forward log messages through pino logger\n logger[message.level](message.message);\n break;\n }\n case 'result':\n result = message.data;\n break;\n\n case 'error':\n hasError = true;\n logger.error(`Worker error: ${message.error}`);\n if (message.stack) {\n logger.error(message.stack);\n }\n break;\n }\n } catch {\n logger.error(`Failed to parse worker protocol message: ${line}`);\n }\n } else {\n // This is user output from console.log - pass it through transparently\n console.log(line);\n }\n });\n\n // Pass through stderr for user's console.error\n child.stderr!.on('data', (data: Buffer) => {\n process.stderr.write(data);\n });\n\n // Handle process exit\n child.on('exit', (code: number | null, signal: string | null) => {\n if (this.currentProcess?.pid === child.pid) {\n this.currentProcess = null;\n }\n\n if (signal) {\n reject(new Error(`Worker terminated by signal: ${signal}`));\n } else if (code === 0) {\n resolve(result);\n } else {\n if (!hasError) {\n logger.error(`Worker exited with code ${code}`);\n }\n reject(new Error(`Worker exited with code ${code}`));\n }\n });\n\n // Handle spawn errors\n child.on('error', (error: Error) => {\n this.currentProcess = null;\n reject(new Error(`Failed to spawn worker: ${error.message}`));\n });\n\n // Send configuration to worker via stdin\n child.stdin?.write(JSON.stringify(config) + '\\n');\n child.stdin?.end();\n });\n }\n\n /**\n * Kill the currently running subprocess\n */\n kill(): void {\n if (this.currentProcess) {\n const processToKill = this.currentProcess;\n this.currentProcess.kill('SIGTERM');\n\n // Fallback to SIGKILL after 5 seconds\n setTimeout(() => {\n // exitCode is null if the process is still running\n if (processToKill && processToKill.exitCode === null) {\n logger.warn('Child process did not terminate, using SIGKILL');\n processToKill.kill('SIGKILL');\n }\n }, 5000);\n }\n }\n\n /**\n * Check if a subprocess is currently running\n */\n isRunning(): boolean {\n return this.currentProcess !== null;\n }\n}\n","import * as path from 'path';\n\nexport interface WorkerCommand {\n command: string;\n args: string[];\n}\n\n/**\n * Default workers mapped by file extension\n */\nconst DEFAULT_WORKERS: Record<string, WorkerCommand> = {\n '.ts': {\n command: 'node',\n args: [], // Will be resolved dynamically\n },\n '.cts': {\n command: 'node',\n args: [], // Will be resolved dynamically\n },\n '.mts': {\n command: 'node',\n args: [], // Will be resolved dynamically\n },\n '.tsx': {\n command: 'node',\n args: [], // Will be resolved dynamically\n },\n '.jsx': {\n command: 'node',\n args: [], // Will be resolved dynamically\n },\n '.js': {\n command: 'node',\n args: [], // Will be resolved dynamically\n },\n '.mjs': {\n command: 'node',\n args: [], // Will be resolved dynamically\n },\n '.cjs': {\n command: 'node',\n args: [], // Will be resolved dynamically\n },\n '.py': {\n command: 'python3',\n args: ['-m', 'lmnr.cli.worker'],\n },\n};\n\n/**\n * Get the worker command for a given file path or module.\n * Resolves the TypeScript worker dynamically from @lmnr-ai/lmnr package.\n */\nexport function getWorkerCommand(\n filePath?: string,\n options?: { pythonModule?: string },\n): WorkerCommand {\n // If Python module mode, always use Python worker\n if (options?.pythonModule) {\n return {\n command: 'python3',\n args: ['-m', 'lmnr.cli.worker'],\n };\n }\n\n // Otherwise determine by file extension\n if (!filePath) {\n throw new Error('Either filePath or pythonModule must be provided');\n }\n\n const ext = path.extname(filePath);\n\n if (!DEFAULT_WORKERS[ext]) {\n throw new Error(\n `Unsupported file extension: ${ext}. ` +\n `Supported extensions: ${Object.keys(DEFAULT_WORKERS).join(', ')}`,\n );\n }\n\n const worker = DEFAULT_WORKERS[ext];\n\n // For TypeScript/JavaScript files, resolve the worker from @lmnr-ai/lmnr\n if (['.ts', '.tsx', '.js', '.mjs', '.cjs', '.mts', '.cts', '.jsx'].includes(ext)) {\n try {\n // Try to resolve the worker from @lmnr-ai/lmnr package\n const workerPath = require.resolve('@lmnr-ai/lmnr/dist/cli/worker/index.cjs');\n return {\n command: worker.command,\n args: [workerPath],\n };\n } catch (error) {\n throw new Error(\n 'Failed to resolve TypeScript/JavaScript worker from @lmnr-ai/lmnr package. ' +\n 'Make sure @lmnr-ai/lmnr is installed. ' +\n `Error: ${error instanceof Error ? error.message : String(error)}`,\n );\n }\n }\n\n return worker;\n}\n\n/**\n * Get a custom worker command with overrides.\n * Allows users to specify custom commands via CLI flags.\n */\nexport function getCustomWorkerCommand(\n command: string,\n args: string[],\n): WorkerCommand {\n return { command, args };\n}\n","import { LaminarClient } from '@lmnr-ai/client';\nimport {\n type CachedSpan,\n type RolloutHandshakeEvent,\n type RolloutParam,\n type RolloutRunEvent,\n type WorkerConfig,\n} from '@lmnr-ai/types';\nimport chokidar from 'chokidar';\nimport * as path from 'path';\nimport { v4 as uuidv4 } from 'uuid';\n\nimport { startCacheServer } from '../cache-server';\nimport { createSSEClient, SSEClient } from '../sse-client';\nimport { SubprocessManager } from '../subprocess/executor';\nimport { initializeLogger } from '../utils';\nimport { getWorkerCommand } from '../worker-registry';\n\ninterface FunctionMetadata {\n name: string; // The span name from observe({ name: '...' })\n exportName: string; // The actual export/variable name\n params: RolloutParam[];\n}\n\nconst logger = initializeLogger();\n\n// Extensions that use TypeScript/JavaScript build and runtime discovery\nconst TS_JS_EXTENSIONS = [\n '.ts',\n '.tsx',\n '.js',\n '.mjs',\n '.cjs',\n '.jsx',\n '.mts',\n '.cts',\n];\n\n// All extensions that support metadata discovery\nconst EXTENSIONS_TO_DISCOVER_METADATA = [...TS_JS_EXTENSIONS, '.py'];\n\nexport interface DevOptions {\n projectApiKey?: string;\n baseUrl?: string;\n port?: number;\n grpcPort?: number;\n function?: string;\n frontendPort?: number;\n externalPackages?: string[];\n dynamicImportsToSkip?: string[];\n command?: string;\n commandArgs?: string[];\n pythonModule?: string; // Python module path (e.g., 'src.myfile')\n}\n\ninterface DiscoveredMetadata {\n functionName: string;\n params: RolloutParam[];\n}\n\nconst logLmnrPackageNotFoundAndExit = () => {\n logger.error(\n '@lmnr-ai/lmnr package not found or outdated. ' +\n 'For JS/TS projects, please install the latest version of @lmnr-ai/lmnr in your project: ' +\n 'npm install @lmnr-ai/lmnr\\n' +\n 'You might need to run `lmnr-cli` from the root of your project',\n );\n process.exit(1);\n};\n\n/**\n * Discovers function metadata for TypeScript and JavaScript files by:\n * 1. Extracting TypeScript metadata (params with types from source - TS only)\n * 2. Building and loading the module with esbuild\n * 3. Selecting the appropriate function\n * 4. Matching metadata by span name\n *\n * For JavaScript files, TypeScript metadata extraction fails gracefully, but runtime\n * parameter extraction via regex still works (param names without types).\n */\nconst discoverTypeScriptMetadata = async (\n filePath: string,\n options: { function?: string; externalPackages?: string[]; dynamicImportsToSkip?: string[] },\n): Promise<DiscoveredMetadata> => {\n let extractRolloutFunctions: any;\n let buildFile: any;\n let loadModule: any;\n let selectRolloutFunction: any;\n\n try {\n /* eslint-disable @typescript-eslint/no-require-imports */\n // Use dynamic require to prevent bundler from trying to resolve at build time\n const lmnrPackage = '@lmnr-ai/lmnr';\n extractRolloutFunctions = require(\n `${lmnrPackage}/dist/cli/worker/ts-parser.cjs`,\n ).extractRolloutFunctions;\n const buildModule = require(`${lmnrPackage}/dist/cli/worker/build.cjs`);\n buildFile = buildModule.buildFile;\n loadModule = buildModule.loadModule;\n selectRolloutFunction = buildModule.selectRolloutFunction;\n /* eslint-enable @typescript-eslint/no-require-imports */\n if (!extractRolloutFunctions || !buildFile || !loadModule || !selectRolloutFunction) {\n logLmnrPackageNotFoundAndExit();\n }\n } catch (error: any) {\n if (error.code === 'MODULE_NOT_FOUND') {\n logLmnrPackageNotFoundAndExit();\n }\n // Re-throw any other errors (syntax errors, etc.)\n throw error;\n }\n\n\n // Extract TypeScript metadata\n let paramsMetadata: Map<string, FunctionMetadata> | undefined;\n try {\n paramsMetadata = extractRolloutFunctions(filePath);\n logger.debug(`Extracted TypeScript metadata for ${paramsMetadata?.size} functions`);\n } catch (error) {\n logger.warn(\n 'Failed to extract TypeScript metadata, falling back to runtime parsing: ' +\n (error instanceof Error ? error.message : String(error)),\n );\n }\n\n // Build and load the module\n const moduleText = await buildFile(filePath, {\n externalPackages: options.externalPackages,\n dynamicImportsToSkip: options.dynamicImportsToSkip,\n });\n loadModule({\n filename: filePath,\n moduleText,\n });\n\n // Select the appropriate function\n const selectedFunction = selectRolloutFunction(options.function);\n\n // If we have TypeScript metadata, match by span name and enrich params\n if (paramsMetadata) {\n logger.debug(`Available TS metadata keys: ${Array.from(paramsMetadata.keys()).join(', ')}`);\n logger.debug(\n `Looking for span name: ${selectedFunction.name} ` +\n `(runtime key: ${selectedFunction.exportName})`,\n );\n\n // Search for metadata by span name\n let foundMetadata: FunctionMetadata | null = null;\n for (const [exportName, metadata] of paramsMetadata.entries()) {\n logger.debug(\n `Checking ${exportName}: span name = ${metadata.name}, export name = ${exportName}`,\n );\n if (metadata.name === selectedFunction.name) {\n foundMetadata = metadata;\n logger.debug(`Match. Export name: ${exportName}, span name: ${metadata.name}`);\n break;\n }\n }\n\n if (foundMetadata) {\n selectedFunction.params = foundMetadata.params;\n logger.debug(`Using TypeScript metadata for span: ${selectedFunction.name}`);\n } else {\n logger.info(`No TypeScript metadata found for span name: ${selectedFunction.name}`);\n }\n }\n\n return {\n functionName: selectedFunction.name,\n params: selectedFunction.params || [],\n };\n};\n\n/**\n * Helper to execute subprocess commands\n */\nconst execCommand = async (\n command: string,\n args: string[],\n): Promise<{ stdout: string; stderr: string }> => new Promise((resolve, reject) => {\n // eslint-disable-next-line @typescript-eslint/no-require-imports\n const { spawn } = require('child_process');\n const child = spawn(command, args);\n let stdout = '';\n let stderr = '';\n\n child.stdout.on('data', (data: Buffer) => {\n stdout += data.toString();\n });\n child.stderr.on('data', (data: Buffer) => {\n stderr += data.toString();\n });\n\n child.on('close', (code: number | null) => {\n if (code === 0) {\n resolve({ stdout, stderr });\n } else {\n reject(new Error(`Command failed with code ${code}: ${stderr}`));\n }\n });\n\n child.on('error', (error: Error) => {\n reject(error);\n });\n});\n\n/**\n * Discovers function metadata for Python files/modules by calling the lmnr Python CLI\n */\nconst discoverPythonMetadata = async (\n filePathOrModule: string,\n options: DevOptions,\n): Promise<DiscoveredMetadata> => {\n logger.debug(`Discovering Python metadata for ${filePathOrModule}`);\n const args = ['discover'];\n\n // Determine if we're using a file path or module\n if (options.pythonModule) {\n // Module mode: lmnr discover --module src.myfile\n args.push('--module', options.pythonModule);\n } else {\n // Script mode: lmnr discover --file src/myfile.py\n args.push('--file', filePathOrModule);\n }\n\n // Add optional function name\n if (options.function) {\n args.push('--function', options.function);\n }\n\n try {\n // Execute: lmnr discover --file <path> | --module <module> [--function <name>]\n const result = await execCommand('lmnr', args);\n const response = JSON.parse(result.stdout);\n\n // Response format: { \"name\": \"...\", \"params\": [...] }\n return {\n functionName: response.name,\n params: response.params || [],\n };\n } catch (error) {\n const errorMessage = error instanceof Error ? error.message : String(error);\n logger.error(`Failed to discover Python metadata: ${errorMessage}`);\n if (errorMessage.toLowerCase().includes('command not found') ||\n errorMessage.includes('spawn lmnr ENOENT')) {\n logger.info(\n \"HINT: Make sure latest version of `lmnr` python package is installed. \" +\n \"`pip install --upgrade lmnr`, or if you are running this command from a virtual \" +\n \"environment, make sure to activate it. For `uv` users, rerun the command with `uv run`, \" +\n `e.g. \"uv run npx lmnr-cli dev ${filePathOrModule}\"`,\n );\n process.exit(1);\n }\n // Fallback\n const defaultName = options.pythonModule\n ? options.pythonModule.split('.').pop() || 'main'\n : path.basename(filePathOrModule, '.py');\n return {\n functionName: options.function || defaultName,\n params: [],\n };\n }\n};\n\n/**\n * Generic metadata discovery dispatcher that routes to language-specific implementations\n */\nconst discoverFunctionMetadata = async (\n filePathOrModule: string,\n options: DevOptions,\n): Promise<DiscoveredMetadata> => {\n // If pythonModule is set, we're in Python module mode\n if (options.pythonModule) {\n return await discoverPythonMetadata(filePathOrModule, options);\n }\n\n // Otherwise check file extension\n const ext = path.extname(filePathOrModule);\n\n // TypeScript and JavaScript files use the same build/load/select process\n // For JS files, TypeScript metadata extraction will fail, but runtime param extraction works\n if (TS_JS_EXTENSIONS.includes(ext)) {\n return await discoverTypeScriptMetadata(filePathOrModule, options);\n }\n\n if (ext === '.py') {\n return await discoverPythonMetadata(filePathOrModule, options);\n }\n\n // Fallback for unsupported file types\n logger.warn(`No metadata discovery available for ${ext} files`);\n return {\n functionName: options.function || path.basename(filePathOrModule, ext),\n params: [],\n };\n};\n\nfunction newUUID(): string {\n if (typeof crypto !== 'undefined' && typeof crypto.randomUUID === 'function') {\n return crypto.randomUUID();\n }\n return uuidv4();\n}\n\nfunction getFrontendUrl(baseUrl?: string, frontendPort?: number): string {\n let url = baseUrl ?? 'https://api.lmnr.ai';\n if (url === 'https://api.lmnr.ai') {\n url = 'https://www.laminar.sh';\n }\n url = url.replace(/\\/$/, '');\n\n if (/localhost|127\\.0\\.0\\.1/.test(url)) {\n const port = frontendPort ?? url.match(/:\\d{1,5}$/g)?.[0]?.slice(1) ?? 5667;\n url = url.replace(/:\\d{1,5}$/g, '');\n return `${url}:${port}`;\n }\n\n return url;\n}\n\n/**\n * Parses request arguments, attempting JSON parse for strings\n */\nconst tryParseArg = (arg: unknown) => {\n if (typeof arg === 'string') {\n try {\n // eslint-disable-next-line @typescript-eslint/no-unsafe-return\n return JSON.parse(arg);\n } catch {\n return arg;\n }\n }\n return arg;\n};\n\n/**\n * Handles a run event from the backend\n */\nconst handleRunEvent = async (\n event: RolloutRunEvent,\n sessionId: string,\n filePathOrModule: string,\n client: LaminarClient,\n cacheServerPort: number,\n cache: Map<string, CachedSpan>,\n setMetadata: (metadata: any) => void,\n options: DevOptions,\n subprocessManager: SubprocessManager,\n): Promise<void> => {\n logger.debug('Received run event');\n\n const { trace_id, path_to_count, args: rawArgs, overrides } = event.data;\n\n const parsedArgs = Array.isArray(rawArgs)\n ? rawArgs.map(tryParseArg)\n : (Object.fromEntries(\n Object.entries(rawArgs).map(([key, value]) => [key, tryParseArg(value)]),\n ) as Record<string, any>);\n\n cache.clear();\n setMetadata({\n pathToCount: {},\n overrides: overrides,\n });\n\n try {\n // Check if we should populate cache from a previous trace\n if (!trace_id || trace_id.trim() === '') {\n logger.info('No spans in cache, starting fresh');\n } else {\n // Query spans from the backend to populate cache\n const paths = Object.keys(path_to_count || {});\n if (paths.length === 0) {\n logger.info('No spans to cache, starting fresh');\n } else {\n const query = `\n SELECT name, input, output, attributes, path\n FROM spans\n WHERE trace_id = {traceId:UUID}\n AND path IN {paths:String[]}\n ORDER BY start_time ASC\n `;\n\n logger.debug(`Querying spans from trace ${trace_id}...`);\n const spans = await client.sql.query(query, {\n traceId: trace_id,\n paths: paths,\n });\n logger.debug(`Received ${spans.length} spans from backend`);\n\n // Group spans by path and filter to first N per path\n const spansByPath: Record<string, any[]> = {};\n for (const span of spans) {\n const path = span.path as string;\n if (!spansByPath[path]) {\n spansByPath[path] = [];\n }\n spansByPath[path].push(span);\n }\n\n for (const [path, pathSpans] of Object.entries(spansByPath)) {\n const maxCount = path_to_count?.[path] || 0;\n const spansToCache = pathSpans.slice(0, maxCount);\n\n spansToCache.forEach((span, index) => {\n // Parse JSON fields\n let parsedInput = span.input;\n let parsedOutput = span.output;\n let parsedAttributes = span.attributes;\n\n try {\n parsedInput =\n typeof span.input === 'string' ? JSON.parse(span.input) : span.input;\n } catch {\n // Keep as string\n }\n\n try {\n parsedOutput =\n typeof span.output === 'string' ? span.output : JSON.stringify(span.output);\n } catch {\n parsedOutput = String(span.output);\n }\n\n try {\n parsedAttributes =\n typeof span.attributes === 'string'\n ? JSON.parse(span.attributes)\n : span.attributes;\n } catch {\n parsedAttributes = {};\n }\n\n const cachedSpan: CachedSpan = {\n name: span.name,\n input: parsedInput,\n output: parsedOutput,\n attributes: parsedAttributes,\n };\n\n const cacheKey = `${index}:${path}`;\n cache.set(cacheKey, cachedSpan);\n });\n\n logger.info(`Cached ${spansToCache.length} spans for path: ${path}`);\n }\n\n // Store metadata in cache server\n setMetadata({\n pathToCount: path_to_count || {},\n overrides,\n });\n }\n }\n\n // Parse baseUrl similar to how evaluations does it\n const baseUrl = options.baseUrl ?? process.env.LMNR_BASE_URL ?? 'https://api.lmnr.ai';\n const httpPort =\n options.port ??\n (baseUrl.match(/:\\d{1,5}$/g)\n ? parseInt(baseUrl.match(/:\\d{1,5}$/g)![0].slice(1))\n : 443);\n const grpcPort = options.grpcPort ?? 8443;\n\n // Prepare environment variables for child process\n const env: Record<string, string> = {\n LMNR_ROLLOUT_SESSION_ID: sessionId,\n LMNR_ROLLOUT_STATE_SERVER_ADDRESS: `http://localhost:${cacheServerPort}`,\n };\n\n // Prepare worker configuration\n const workerConfig: WorkerConfig = {\n filePath: options.pythonModule ? undefined : filePathOrModule,\n modulePath: options.pythonModule,\n functionName: options.function,\n args: parsedArgs,\n env,\n cacheServerPort,\n baseUrl,\n projectApiKey: options.projectApiKey,\n httpPort,\n grpcPort,\n externalPackages: options.externalPackages,\n dynamicImportsToSkip: options.dynamicImportsToSkip,\n };\n\n // Get worker command\n const workerCommand = options.command\n ? { command: options.command, args: options.commandArgs ?? [] }\n : getWorkerCommand(options.pythonModule ? undefined : filePathOrModule, options);\n\n try {\n await client.rolloutSessions.setStatus({\n sessionId,\n status: 'RUNNING',\n });\n } catch (error: any) {\n logger.error(\n `Error setting rollout session status: ${error instanceof Error ? error.message : error}`,\n );\n }\n\n // Execute the rollout function in subprocess\n await subprocessManager.execute({\n command: workerCommand.command,\n args: workerCommand.args,\n config: workerConfig,\n });\n\n try {\n await client.rolloutSessions.setStatus({\n sessionId,\n status: 'FINISHED',\n });\n } catch (error: any) {\n logger.error(\n `Error setting rollout session status: ${error instanceof Error ? error.message : error}`,\n );\n }\n } catch (error: any) {\n logger.error(`Error handling run event: ${error instanceof Error ? error.message : error}`);\n if (error instanceof Error && error.stack) {\n logger.error(error.stack);\n }\n try {\n await client.rolloutSessions.setStatus({\n sessionId,\n status: 'FINISHED',\n });\n } catch (error: any) {\n logger.error(\n `Error setting rollout session status: ${error instanceof Error ? error.message : error}`,\n );\n }\n }\n};\n\n/**\n * Main dev command handler\n */\nexport async function runDev(filePath?: string, options: DevOptions = {}): Promise<void> {\n // Determine the actual path/module to use\n const isPythonModule = !!options.pythonModule;\n const filePathOrModule = filePath || options.pythonModule!;\n let didLogHandshake = false;\n\n // Generate session ID\n const sessionId = newUUID();\n\n // Initialize Laminar client\n const client = new LaminarClient({\n baseUrl: options.baseUrl,\n projectApiKey: options.projectApiKey,\n port: options.port,\n });\n\n // Start cache server\n logger.debug('Starting cache server...');\n const { port: cacheServerPort, server: cacheServer, cache, setMetadata } =\n await startCacheServer();\n logger.debug(`Cache server started on port ${cacheServerPort}`);\n\n // Create subprocess manager\n const subprocessManager = new SubprocessManager();\n\n // Get function metadata (name and params)\n let functionName = options.function;\n let params: RolloutParam[] = [];\n\n try {\n // Check if we should discover metadata\n const shouldDiscover =\n isPythonModule ||\n (filePath && EXTENSIONS_TO_DISCOVER_METADATA.includes(path.extname(filePath)));\n\n if (shouldDiscover) {\n logger.debug('Discovering rollout functions...');\n const metadata = await discoverFunctionMetadata(filePathOrModule, options);\n functionName = metadata.functionName;\n params = metadata.params;\n\n logger.info(`Serving function: ${functionName}`);\n logger.debug(`Function parameters: ${JSON.stringify(params, null, 2)}`);\n } else if (filePath) {\n // Unsupported file type\n functionName = options.function || path.basename(filePath, path.extname(filePath));\n logger.warn(`Metadata discovery not available for ${path.extname(filePath)} files`);\n }\n } catch (error) {\n logger.error(\n 'Failed to discover rollout functions: ' +\n (error instanceof Error ? error.message : String(error)),\n );\n cacheServer.close();\n throw error;\n }\n\n // Setup file watcher for hot reload\n logger.debug('Setting up file watcher...');\n const watcher = chokidar.watch('.', {\n ignored: (path: string) => {\n const ignoredDirs = [\n 'node_modules',\n '.git',\n 'dist',\n 'build',\n '.next',\n 'coverage',\n '.turbo',\n 'tmp',\n 'temp',\n 'venv',\n '.venv',\n 'virtualenv',\n '.virtualenv',\n '__pycache__',\n '.pytest_cache',\n '.ruff_cache',\n '.mypy_cache',\n '.cache',\n '.DS_Store',\n ];\n\n const pathSegments = path.split(/[/\\\\]/);\n if (pathSegments.some((segment) => ignoredDirs.includes(segment))) {\n return true;\n }\n\n if (path.endsWith('.log') || path.endsWith('.map')) {\n return true;\n }\n\n return false;\n },\n persistent: true,\n ignoreInitial: true,\n awaitWriteFinish: {\n stabilityThreshold: 100,\n pollInterval: 100,\n },\n });\n\n // Create SSE client\n logger.debug('Setting up SSE client...');\n let sseClient: SSEClient | null = null;\n\n try {\n sseClient = createSSEClient({\n client,\n sessionId,\n params: params,\n name: functionName ?? '',\n });\n\n // Register all event listeners BEFORE connecting\n sseClient.on('heartbeat', () => {\n logger.debug('Heartbeat received');\n });\n\n sseClient.on('run', (event: RolloutRunEvent) => {\n if (subprocessManager.isRunning()) {\n logger.warn('Rollout is already running, skipping new run');\n return;\n }\n\n handleRunEvent(\n event,\n sessionId,\n filePathOrModule,\n client,\n cacheServerPort,\n cache,\n setMetadata,\n options,\n subprocessManager,\n ).catch((error) => {\n logger.error(\n 'Unhandled error in run event handler: ' +\n (error instanceof Error ? error.message : String(error)),\n );\n });\n });\n\n sseClient.on('handshake', (event: RolloutHandshakeEvent) => {\n const projectId = event.data.project_id;\n const sessionId = event.data.session_id;\n const frontendUrl = getFrontendUrl(options.baseUrl, options.frontendPort);\n if (!didLogHandshake) {\n logger.info(\n `View your session at ${frontendUrl}/project/${projectId}/rollout-sessions/${sessionId}`,\n );\n }\n didLogHandshake = true;\n });\n\n sseClient.on('error', (error: Error) => {\n logger.warn(`Error connecting to backend: ${error.message}`);\n });\n\n sseClient.on('reconnecting', () => {\n logger.info('Reconnecting to backend...');\n });\n\n sseClient.on('heartbeat_timeout', () => {\n logger.debug('Heartbeat timeout, reconnecting...');\n });\n\n sseClient.on('stop', () => {\n logger.debug('Cancelling current run...');\n subprocessManager.kill();\n logger.info('Current run cancelled');\n });\n\n // Setup file change handler for hot reload\n watcher.on('change', (changedPath: string) => {\n logger.info(`File changed: ${changedPath}, reloading...`);\n\n // Cancel running subprocess\n if (subprocessManager.isRunning()) {\n logger.warn('Cancelling current run due to file change');\n subprocessManager.kill();\n }\n\n // Re-discover function metadata for supported file types\n if (\n isPythonModule ||\n (filePath &&\n EXTENSIONS_TO_DISCOVER_METADATA.includes(path.extname(filePath)))\n ) {\n discoverFunctionMetadata(filePathOrModule, options)\n .then((metadata) => {\n logger.debug(`Updated function metadata: ${metadata.functionName}`);\n logger.debug(`Updated parameters: ${JSON.stringify(metadata.params, null, 2)}`);\n\n // Update the SSE client with new metadata\n if (sseClient) {\n sseClient.updateMetadata(metadata.params, metadata.functionName);\n logger.debug('Notified backend of metadata changes');\n }\n })\n .catch((error: any) => {\n logger.error(\n 'Failed to update function metadata: ' +\n (error instanceof Error ? error.message : String(error)),\n );\n });\n }\n });\n\n // Handle graceful shutdown\n const shutdown = () => {\n logger.debug('Shutting down...');\n\n // Close file watcher\n logger.debug('Closing file watcher...');\n watcher\n .close()\n .catch((error: any) => {\n logger.error(\n `Failed to close file watcher: ${error instanceof Error ? error.message : error}`,\n );\n });\n\n // Kill any running subprocess\n subprocessManager.kill();\n\n // Delete the rollout session\n logger.debug('Deleting rollout session...');\n client.rolloutSessions\n .delete({ sessionId })\n .then(() => {\n if (sseClient) {\n sseClient.shutdown();\n }\n\n cacheServer.close(() => {\n logger.debug('Cache server closed');\n });\n process.exit(0);\n })\n .catch((error: any) => {\n logger.warn(\n `Failed to delete rollout session: ${error instanceof Error ? error.message : error}`,\n );\n process.exit(1);\n });\n };\n\n process.on('SIGINT', shutdown);\n process.on('SIGTERM', shutdown);\n\n // Keep stdin open to prevent process from exiting\n process.stdin.resume();\n\n // Connect to backend and start listening\n logger.debug('Connecting to backend...');\n await sseClient.connectAndListen();\n } catch (error) {\n logger.error(\n 'Failed to start dev command: ' + (error instanceof Error ? error.message : String(error)),\n );\n\n // Try to delete the rollout session before exiting\n try {\n await client.rolloutSessions.delete({ sessionId });\n } catch {\n // Ignore delete errors during error cleanup\n }\n\n await watcher.close();\n cacheServer.close(() => {\n process.exit(1);\n });\n }\n}\n","#!/usr/bin/env node\n\nimport { Command } from 'commander';\n\nimport { version } from '../package.json';\nimport { runDev } from './commands/dev';\n\nasync function main() {\n const program = new Command();\n\n program\n .name('lmnr-cli')\n .description('CLI for Laminar AI rollout debugging')\n .version(version, '-v, --version', 'display version number');\n\n program\n .command('dev')\n .description('Start a rollout debugging session')\n .argument(\n '[file]',\n 'Path to file containing the agent function(s). Either `file` or `-m` must be provided.',\n )\n .option(\n '-m, --python-module <module>',\n 'Python module path (e.g., src.myfile). Either `file` or `-m` must be provided.',\n )\n .option(\n '--function <name>',\n 'Specific function to serve (if multiple rollout functions found)',\n )\n .option(\n '--project-api-key <key>',\n 'Project API key. If not provided, reads from LMNR_PROJECT_API_KEY env variable',\n )\n .option(\n '--base-url <url>',\n 'Base URL for the Laminar API. Defaults to https://api.lmnr.ai or LMNR_BASE_URL env variable',\n )\n .option('--port <port>', 'Port for the Laminar API. Defaults to 443', (val) =>\n parseInt(val, 10),\n )\n .option(\n '--grpc-port <port>',\n 'Port for the Laminar gRPC backend. Defaults to 8443',\n (val) => parseInt(val, 10),\n )\n .option(\n '--frontend-port <port>',\n 'Port for the Laminar frontend. Defaults to 5667',\n (val) => parseInt(val, 10),\n )\n .option(\n '--external-packages <packages...>',\n '[ADVANCED] List of packages to pass as external to esbuild. This will not link ' +\n 'the packages directly into the dev file, but will instead require them at runtime. ' +\n 'Read more: https://esbuild.github.io/api/#external',\n )\n .option(\n '--dynamic-imports-to-skip <modules...>',\n '[ADVANCED] List of module names to skip when encountered as dynamic imports. ' +\n 'These dynamic imports will resolve to an empty module to prevent build failures. ' +\n 'This is meant to skip the imports that are not used in the rollout itself.',\n )\n .option(\n '--command <command>',\n '[ADVANCED] Custom command to run the worker (e.g., python3, node)',\n )\n .option(\n '--command-args <args...>',\n '[ADVANCED] Arguments for the custom command',\n )\n .action(async (file: string | undefined, options) => {\n // Validation: must have either file or python-module, but not both\n if (!file && !options.pythonModule) {\n console.error('Error: Must provide either a file path or --python-module (-m) flag');\n process.exit(1);\n }\n if (file && options.pythonModule) {\n console.error('Error: Cannot specify both file path and --python-module (-m) flag');\n process.exit(1);\n }\n\n await runDev(file, options);\n })\n .addHelpText(\n 'after',\n `\nExamples:\n $ lmnr-cli dev agent.ts # TypeScript file\n $ lmnr-cli dev agent.py # Python file (script mode)\n $ lmnr-cli dev -m src.agent # Python module (module mode)\n $ lmnr-cli dev agent.ts --function myAgent # Specific function\n`,\n );\n\n await program.parseAsync();\n}\n\nmain().catch((err) => {\n console.error(err instanceof Error ? err.message : err);\n process.exit(1);\n});\n"],"x_google_ignoreList":[1,2],"mappings":"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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "lmnr-cli",
3
- "version": "0.1.0-alpha.0",
3
+ "version": "0.1.1",
4
4
  "description": "CLI for Laminar AI rollout debugging",
5
5
  "main": "dist/index.cjs",
6
6
  "bin": {
@@ -30,8 +30,16 @@
30
30
  "uuid": "^13.0.0"
31
31
  },
32
32
  "devDependencies": {
33
- "@lmnr-ai/types": "0.8.2",
34
- "@lmnr-ai/client": "0.8.2"
33
+ "@lmnr-ai/types": "0.8.3",
34
+ "@lmnr-ai/client": "0.8.3"
35
+ },
36
+ "peerDependencies": {
37
+ "@lmnr-ai/lmnr": "*"
38
+ },
39
+ "peerDependenciesMeta": {
40
+ "@lmnr-ai/lmnr": {
41
+ "optional": true
42
+ }
35
43
  },
36
44
  "scripts": {
37
45
  "build": "tsdown",