{"version":3,"file":"cli.cjs","names":["logger","initializeLogger","LaminarClient","errorMessage","loadFromPaths","writeToFile","logger","initializeLogger","getDirname","fs","initializeLogger","Command","version","errorMessage"],"sources":["../src/cli/datasets.ts","../src/cli/evals.ts","../src/cli/index.ts"],"sourcesContent":["import { LaminarClient } from \"@lmnr-ai/client\";\nimport { errorMessage, type StringUUID } from \"@lmnr-ai/types\";\n\nimport { Datapoint } from \"../evaluations\";\nimport { initializeLogger } from \"../utils\";\nimport { loadFromPaths, printToConsole, writeToFile } from \"./file-utils\";\n\nconst logger = initializeLogger();\nconst DEFAULT_DATASET_PULL_BATCH_SIZE = 100;\nconst DEFAULT_DATASET_PUSH_BATCH_SIZE = 100;\n\ninterface DatasetCommandOptions {\n  projectApiKey?: string;\n  baseUrl?: string;\n  port?: number;\n}\n\n/**\n * Pull all data from a dataset in batches.\n */\nconst pullAllData = async <D = any, T = any>(\n  client: LaminarClient,\n  identifier: { name?: string; id?: StringUUID },\n  batchSize: number = DEFAULT_DATASET_PULL_BATCH_SIZE,\n  offset: number = 0,\n  limit?: number,\n): Promise<Datapoint<D, T>[]> => {\n  let hasMore = true;\n  let currentOffset = offset;\n  const stopAt = limit !== undefined ? offset + limit : undefined;\n\n  const result: Datapoint<D, T>[] = [];\n\n  while (hasMore && (stopAt === undefined || currentOffset < stopAt)) {\n    const data = await client.datasets.pull<D, T>({\n      ...identifier,\n      offset: currentOffset,\n      limit: batchSize,\n    });\n\n    result.push(...data.items);\n\n    // Stop if we received no items or fewer items than requested (end of data)\n    if (data.items.length === 0 || data.items.length < batchSize) {\n      hasMore = false;\n    } else if (stopAt !== undefined && currentOffset + batchSize >= stopAt) {\n      hasMore = false;\n    } else if (\n      data.totalCount !== undefined &&\n      currentOffset + batchSize >= data.totalCount\n    ) {\n      hasMore = false;\n    }\n\n    currentOffset += batchSize;\n  }\n\n  if (limit !== undefined) {\n    return result.slice(0, limit);\n  }\n\n  return result;\n};\n\n/**\n * Handle datasets list command.\n */\nexport const handleDatasetsList = async (\n  options: DatasetCommandOptions,\n): Promise<void> => {\n  const client = new LaminarClient({\n    projectApiKey: options.projectApiKey,\n    baseUrl: options.baseUrl,\n    port: options.port,\n  });\n\n  try {\n    const datasets = await client.datasets.listDatasets();\n\n    if (datasets.length === 0) {\n      console.log(\"No datasets found.\");\n      return;\n    }\n\n    // Print table header\n    const idWidth = 36; // UUID length\n    const createdAtWidth = 19; // YYYY-MM-DD HH:MM:SS format\n\n    console.log(\n      `\\n${\"ID\".padEnd(idWidth)}  ${\"Created At\".padEnd(createdAtWidth)}  Name`,\n    );\n    console.log(\n      `${\"-\".repeat(idWidth)}  ${\"-\".repeat(createdAtWidth)}  ${\"-\".repeat(20)}`,\n    );\n\n    // Print each dataset row\n    for (const dataset of datasets) {\n      const createdAt = new Date(dataset.createdAt);\n      const createdAtStr = createdAt\n        .toISOString()\n        .replace(\"T\", \" \")\n        .substring(0, 19);\n      console.log(\n        `${dataset.id.padEnd(idWidth)}  ${createdAtStr.padEnd(createdAtWidth)}  ${dataset.name}`,\n      );\n    }\n\n    console.log(`\\nTotal: ${datasets.length} dataset(s)\\n`);\n  } catch (error) {\n    logger.error(`Failed to list datasets: ${errorMessage(error)}`);\n  }\n};\n\n/**\n * Handle datasets push command.\n */\nexport const handleDatasetsPush = async (\n  paths: string[],\n  options: DatasetCommandOptions & {\n    name?: string;\n    id?: StringUUID;\n    recursive?: boolean;\n    batchSize?: number;\n  },\n): Promise<void> => {\n  if (!options.name && !options.id) {\n    logger.error(\"Either name or id must be provided\");\n    return;\n  }\n\n  if (options.name && options.id) {\n    logger.error(\"Only one of name or id must be provided\");\n    return;\n  }\n\n  const client = new LaminarClient({\n    projectApiKey: options.projectApiKey,\n    baseUrl: options.baseUrl,\n    port: options.port,\n  });\n\n  const data = await loadFromPaths(paths, options.recursive);\n\n  if (data.length === 0) {\n    logger.warn(\"No data to push. Skipping\");\n    return;\n  }\n\n  const identifier = options.name ? { name: options.name } : { id: options.id };\n\n  try {\n    await client.datasets.push({\n      points: data,\n      ...identifier,\n      batchSize: options.batchSize ?? DEFAULT_DATASET_PUSH_BATCH_SIZE,\n    });\n    logger.info(\n      `Pushed ${data.length} data points to dataset ${options.name || options.id}`,\n    );\n  } catch (error) {\n    logger.error(`Failed to push dataset: ${errorMessage(error)}`);\n  }\n};\n\n/**\n * Handle datasets pull command.\n */\nexport const handleDatasetsPull = async (\n  outputPath: string | undefined,\n  options: DatasetCommandOptions & {\n    name?: string;\n    id?: StringUUID;\n    outputFormat?: \"json\" | \"csv\" | \"jsonl\";\n    batchSize?: number;\n    limit?: number;\n    offset?: number;\n  },\n): Promise<void> => {\n  if (!options.name && !options.id) {\n    logger.error(\"Either name or id must be provided\");\n    return;\n  }\n\n  if (options.name && options.id) {\n    logger.error(\"Only one of name or id must be provided\");\n    return;\n  }\n\n  const client = new LaminarClient({\n    projectApiKey: options.projectApiKey,\n    baseUrl: options.baseUrl,\n    port: options.port,\n  });\n\n  const identifier = options.name ? { name: options.name } : { id: options.id };\n\n  try {\n    const result = await pullAllData(\n      client,\n      identifier,\n      options.batchSize ?? DEFAULT_DATASET_PULL_BATCH_SIZE,\n      options.offset ?? 0,\n      options.limit,\n    );\n\n    if (outputPath) {\n      await writeToFile(outputPath, result, options.outputFormat);\n      logger.info(\n        `Successfully pulled ${result.length} data points to ${outputPath}`,\n      );\n    } else {\n      printToConsole(result, options.outputFormat ?? \"json\");\n    }\n  } catch (error) {\n    logger.error(`Failed to pull dataset: ${errorMessage(error)}`);\n  }\n};\n\n/**\n * Handle datasets create command.\n */\nexport const handleDatasetsCreate = async (\n  name: string,\n  paths: string[],\n  options: DatasetCommandOptions & {\n    outputFile: string;\n    outputFormat?: \"json\" | \"csv\" | \"jsonl\";\n    recursive?: boolean;\n    batchSize?: number;\n  },\n): Promise<void> => {\n  const client = new LaminarClient({\n    projectApiKey: options.projectApiKey,\n    baseUrl: options.baseUrl,\n    port: options.port,\n  });\n\n  // Load data from input files\n  const data = await loadFromPaths(paths, options.recursive);\n\n  if (data.length === 0) {\n    logger.warn(\"No data to push. Skipping\");\n    return;\n  }\n\n  // Push data to create/populate the dataset\n  logger.info(`Pushing ${data.length} data points to dataset '${name}'...`);\n\n  try {\n    await client.datasets.push({\n      points: data,\n      name,\n      batchSize: options.batchSize ?? DEFAULT_DATASET_PUSH_BATCH_SIZE,\n      createDataset: true,\n    });\n    logger.info(\n      `Successfully pushed ${data.length} data points to dataset '${name}'`,\n    );\n  } catch (error) {\n    logger.error(`Failed to create dataset: ${errorMessage(error)}`);\n    return;\n  }\n\n  // Pull data back from the dataset\n  logger.info(`Pulling data from dataset '${name}'...`);\n\n  try {\n    const result = await pullAllData(\n      client,\n      { name },\n      options.batchSize ?? DEFAULT_DATASET_PULL_BATCH_SIZE,\n      0,\n      undefined,\n    );\n\n    // Save to output file\n    await writeToFile(options.outputFile, result, options.outputFormat);\n\n    logger.info(\n      `Successfully created dataset '${name}' ` +\n        `and saved ${result.length} datapoints to ${options.outputFile}`,\n    );\n  } catch (error) {\n    logger.error(\n      \"Failed to pull dataset after creation: \" + errorMessage(error),\n    );\n  }\n};\n","import * as esbuild from \"esbuild\";\nimport * as fs from \"fs/promises\";\n\nimport { Evaluation } from \"../evaluations\";\nimport { getDirname, initializeLogger } from \"../utils\";\n\nconst logger = initializeLogger();\n\n// esbuild plugin to skip dynamic imports\nconst createSkipDynamicImportsPlugin = (\n  skipModules: string[],\n): esbuild.Plugin => ({\n  name: \"skip-dynamic-imports\",\n  setup(build) {\n    if (!skipModules || skipModules.length === 0) return;\n\n    build.onResolve({ filter: /.*/ }, (args) => {\n      // Only handle dynamic imports\n      if (args.kind === \"dynamic-import\" && skipModules.includes(args.path)) {\n        logger.warn(`Skipping dynamic import: ${args.path}`);\n        // Return a virtual module that exports an empty object\n        return {\n          path: args.path,\n          namespace: \"lmnr-skip-dynamic-import\",\n        };\n      }\n    });\n\n    // Provide empty module content for skipped dynamic imports\n    build.onLoad(\n      { filter: /.*/, namespace: \"lmnr-skip-dynamic-import\" },\n      (args) => ({\n        contents: \"export default {};\",\n        loader: \"js\",\n      }),\n    );\n  },\n});\n\nfunction loadModule({\n  filename,\n  moduleText,\n}: {\n  filename: string;\n  moduleText: string;\n}): Evaluation<any, any, any>[] {\n  globalThis._evaluations = [];\n  globalThis._set_global_evaluation = true;\n\n  const __filename = filename;\n  const __dirname = getDirname();\n\n  // add some arguments for proper cjs/esm interop\n\n  new Function(\"require\", \"module\", \"__filename\", \"__dirname\", moduleText)(\n    require,\n    module,\n    __filename,\n    __dirname,\n  );\n\n  // Return the modified _evals global variable\n  return globalThis._evaluations;\n}\n\nexport interface EvalCommandOptions {\n  failOnError?: boolean;\n  outputFile?: string;\n  externalPackages?: string[];\n  dynamicImportsToSkip?: string[];\n  frontendPort?: number;\n}\n\nexport async function runEvaluation(\n  files: string[],\n  options: EvalCommandOptions,\n): Promise<void> {\n  const patterns =\n    files && files.length > 0\n      ? files\n      : // No files provided, use default pattern\n        [\"evals/**/*.eval.{ts,js}\"];\n\n  const evalFiles: string[] = [];\n  for await (const file of fs.glob(patterns)) {\n    evalFiles.push(file);\n  }\n\n  evalFiles.sort();\n\n  if (evalFiles.length === 0) {\n    logger.error(\n      \"No evaluation files found. Please provide a file or \" +\n        \"ensure there are eval files that are named like `*.eval.{ts,js}` in \" +\n        \"the `evals` directory or its subdirectories.\",\n    );\n    process.exit(1);\n  }\n\n  if (files.length === 0) {\n    logger.info(`Located ${evalFiles.length} evaluation files in evals/`);\n  } else {\n    logger.info(`Running ${evalFiles.length} evaluation files.`);\n  }\n\n  const scores: {\n    file: string;\n    scores: Record<string, number>;\n    url: string;\n    evaluationId: string;\n  }[] = [];\n\n  for (const file of evalFiles) {\n    logger.info(`Loading ${file}...`);\n    const buildOptions = {\n      bundle: true,\n      platform: \"node\" as esbuild.Platform,\n      entryPoints: [file],\n      outfile: `tmp_out_${file}.js`,\n      write: false, // will be loaded in memory as a temp file\n      external: [\n        \"@lmnr-ai/lmnr\",\n        \"@lmnr-ai/lmnr/*\",\n        \"@lmnr-ai/client\",\n        \"@lmnr-ai/types\",\n        \"esbuild\",\n        \"fsevents\",\n        \"playwright\",\n        \"puppeteer\",\n        \"puppeteer-core\",\n        \"playwright-core\",\n        ...(options.externalPackages ? options.externalPackages : []),\n      ],\n      plugins: [\n        createSkipDynamicImportsPlugin(options.dynamicImportsToSkip || []),\n      ],\n      treeShaking: true,\n    };\n\n    const result = await esbuild.build(buildOptions);\n\n    if (!result.outputFiles) {\n      logger.error(\n        \"Error when building: No output files found \" +\n          \"it is likely that all eval files are not valid TypeScript or JavaScript files.\",\n      );\n      if (options.failOnError) {\n        process.exit(1);\n      }\n      continue;\n    }\n\n    const outputFileText = result.outputFiles[0].text;\n\n    const evaluations = loadModule({\n      filename: file,\n      moduleText: outputFileText,\n    });\n\n    logger.info(`Loaded ${evaluations.length} evaluations from ${file}`);\n\n    for (const evaluation of evaluations) {\n      if (!evaluation?.run) {\n        logger.error(`Evaluation ${file} does not properly call evaluate()`);\n        if (options.failOnError) {\n          process.exit(1);\n        }\n        continue;\n      }\n\n      if (options.frontendPort) {\n        evaluation.setFrontendPort(options.frontendPort);\n      }\n      const evalResult = await evaluation.run();\n      scores.push({\n        file,\n        scores: evalResult?.averageScores ?? {},\n        url: evalResult?.url ?? \"\",\n        evaluationId: evalResult?.evaluationId ?? \"\",\n      });\n    }\n  }\n\n  if (options.outputFile) {\n    await fs.writeFile(options.outputFile, JSON.stringify(scores, null, 2));\n  }\n}\n","#!/usr/bin/env node\n\nimport { errorMessage } from \"@lmnr-ai/types\";\nimport { Command } from \"commander\";\n\nimport { version } from \"../../package.json\";\nimport { Evaluation } from \"../evaluations\";\nimport { initializeLogger } from \"../utils\";\nimport {\n  handleDatasetsCreate,\n  handleDatasetsList,\n  handleDatasetsPull,\n  handleDatasetsPush,\n} from \"./datasets\";\nimport { runEvaluation } from \"./evals\";\n\nconst logger = initializeLogger();\n\ndeclare global {\n  var _evaluations: Evaluation<any, any, any>[] | undefined;\n  var _set_global_evaluation: boolean;\n}\n\nasync function cli() {\n  const program = new Command();\n\n  program\n    .name(\"lmnr\")\n    .description(\n      \"CLI for Laminar. Use `lmnr <subcommand> --help` for more information.\",\n    )\n    .version(version, \"-v, --version\", \"display version number\");\n\n  // Eval command\n  program\n    .command(\"eval\")\n    .description(\"Run an evaluation\")\n    .argument(\n      \"[files...]\",\n      \"A file or files containing the evaluation to run. If no file is provided, \" +\n        \"the evaluation will run all `*.eval.ts|js` files in the `evals` directory. \" +\n        \"If multiple files are provided, the evaluation will run each file in order.\",\n    )\n    .option(\n      \"--fail-on-error\",\n      \"Fail on error. If specified, will fail if encounters a file that cannot be run\",\n    )\n    .option(\n      \"--output-file <file>\",\n      \"Output file to write the results to. Outputs are written in JSON format.\",\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 eval 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 evaluation itself.\",\n    )\n    .option(\n      \"--frontend-port <port>\",\n      \"Port for the Laminar frontend. Defaults to 5667\",\n      (val) => parseInt(val, 10),\n    )\n    .action(async (files: string[], options) => {\n      await runEvaluation(files, options);\n    });\n\n  const deprecatedDatasetsWarning =\n    \"DeprecationWarning: `lmnr datasets` is deprecated and will be removed in a future version. \" +\n    \"Use `lmnr-cli dataset` instead.\";\n\n  // Datasets command with global options\n  const datasetCmd = program\n    .command(\"datasets\")\n    .description(\n      \"[DEPRECATED] Manage datasets. Use `lmnr-cli dataset` instead.\",\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(\n      \"--port <port>\",\n      \"Port for the Laminar API. Defaults to 443\",\n      (val) => parseInt(val, 10),\n    );\n\n  // Datasets list command\n  datasetCmd\n    .command(\"list\")\n    .description(\"List all datasets\")\n    .action(async (options, cmd) => {\n      process.stderr.write(deprecatedDatasetsWarning + \"\\n\");\n      const parentOpts = cmd.parent?.opts() || {};\n      await handleDatasetsList({ ...parentOpts, ...options });\n    });\n\n  // Datasets push command\n  datasetCmd\n    .command(\"push\")\n    .description(\"Push datapoints to an existing dataset\")\n    .argument(\n      \"<paths...>\",\n      \"Paths to files or directories containing data to push\",\n    )\n    .option(\n      \"-n, --name <name>\",\n      \"Name of the dataset (either name or id must be provided)\",\n    )\n    .option(\n      \"--id <id>\",\n      \"ID of the dataset (either name or id must be provided)\",\n    )\n    .option(\"-r, --recursive\", \"Recursively read files in directories\", false)\n    .option(\n      \"--batch-size <size>\",\n      \"Batch size for pushing data\",\n      (val) => parseInt(val, 10),\n      100,\n    )\n    .action(async (paths: string[], options, cmd) => {\n      process.stderr.write(deprecatedDatasetsWarning + \"\\n\");\n      const parentOpts = cmd.parent?.opts() || {};\n      await handleDatasetsPush(paths, { ...parentOpts, ...options });\n    });\n\n  // Datasets pull command\n  datasetCmd\n    .command(\"pull\")\n    .description(\"Pull data from a dataset\")\n    .argument(\n      \"[output-path]\",\n      \"Path to save the data. If not provided, prints to console\",\n    )\n    .option(\n      \"-n, --name <name>\",\n      \"Name of the dataset (either name or id must be provided)\",\n    )\n    .option(\n      \"--id <id>\",\n      \"ID of the dataset (either name or id must be provided)\",\n    )\n    .option(\n      \"--output-format <format>\",\n      \"Output format (json, csv, jsonl). Inferred from file extension if not provided\",\n    )\n    .option(\n      \"--batch-size <size>\",\n      \"Batch size for pulling data\",\n      (val) => parseInt(val, 10),\n      100,\n    )\n    .option(\"--limit <limit>\", \"Limit number of datapoints to pull\", (val) =>\n      parseInt(val, 10),\n    )\n    .option(\n      \"--offset <offset>\",\n      \"Offset for pagination\",\n      (val) => parseInt(val, 10),\n      0,\n    )\n    .action(async (outputPath: string | undefined, options, cmd) => {\n      process.stderr.write(deprecatedDatasetsWarning + \"\\n\");\n      const parentOpts = cmd.parent?.opts() || {};\n      await handleDatasetsPull(outputPath, { ...parentOpts, ...options });\n    });\n\n  // Datasets create command\n  datasetCmd\n    .command(\"create\")\n    .description(\"Create a dataset from input files\")\n    .argument(\"<name>\", \"Name of the dataset to create\")\n    .argument(\n      \"<paths...>\",\n      \"Paths to files or directories containing data to push\",\n    )\n    .requiredOption(\"-o, --output-file <file>\", \"Path to save the pulled data\")\n    .option(\n      \"--output-format <format>\",\n      \"Output format (json, csv, jsonl). Inferred from file extension if not provided\",\n    )\n    .option(\"-r, --recursive\", \"Recursively read files in directories\", false)\n    .option(\n      \"--batch-size <size>\",\n      \"Batch size for pushing/pulling data\",\n      (val) => parseInt(val, 10),\n      100,\n    )\n    .action(async (name: string, paths: string[], options, cmd) => {\n      process.stderr.write(deprecatedDatasetsWarning + \"\\n\");\n      const parentOpts = cmd.parent?.opts() || {};\n      await handleDatasetsCreate(name, paths, { ...parentOpts, ...options });\n    });\n\n  // If no command provided, show help\n  if (!process.argv.slice(2).length) {\n    program.help();\n    return;\n  }\n\n  await program.parseAsync();\n}\n\ncli().catch((err) => {\n  logger.error(errorMessage(err));\n  throw err;\n});\n"],"mappings":"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"}