{"version":3,"sources":["../src/cli/commands/scenarios/run.ts"],"sourcesContent":["import chalk from \"chalk\";\nimport ora from \"ora\";\nimport {\n  SuitesApiService,\n  type SuiteTarget,\n} from \"@/client-sdk/services/suites\";\nimport { checkApiKey } from \"../../utils/apiKey\";\nimport { failSpinner } from \"../../utils/spinnerError\";\nimport { buildAuthHeaders } from \"@/internal/api/auth\";\nimport { resolveControlPlaneUrl } from \"@/cli/utils/governance/resolveEndpoint\";\n\nfunction parseTarget(targetStr: string): SuiteTarget {\n  const colonIndex = targetStr.indexOf(\":\");\n  if (colonIndex === -1) {\n    console.error(chalk.red(`Error: Invalid target format \"${targetStr}\". Use <type>:<referenceId> (e.g., http:agent_abc123)`));\n    process.exit(1);\n  }\n  const type = targetStr.slice(0, colonIndex);\n  const referenceId = targetStr.slice(colonIndex + 1);\n  if (![\"prompt\", \"http\", \"code\", \"workflow\"].includes(type)) {\n    console.error(chalk.red(`Error: Invalid target type \"${type}\". Must be one of: prompt, http, code, workflow`));\n    process.exit(1);\n  }\n  return { type: type as SuiteTarget[\"type\"], referenceId };\n}\n\nexport const runScenarioCommand = async (\n  id: string,\n  options: { target: string; wait?: boolean; format?: string },\n): Promise<void> => {\n  checkApiKey();\n\n  if (!options.target) {\n    console.error(chalk.red(\"Error: --target is required. Specify what to run the scenario against.\"));\n    console.error(chalk.gray(\"  Example: langwatch scenario run <id> --target http:agent_abc123\"));\n    console.error(chalk.gray(\"  Target types: http, code, workflow, prompt\"));\n    process.exit(1);\n  }\n\n  const target = parseTarget(options.target);\n  const suitesService = new SuitesApiService();\n\n  // Create a temporary suite to execute this scenario\n  const spinner = ora(`Preparing scenario run for \"${id}\"...`).start();\n\n  try {\n    // Create an ephemeral suite for this single scenario run\n    const suite = await suitesService.create({\n      name: `CLI run: scenario ${id}`,\n      description: `Ephemeral suite created by CLI for running scenario ${id}`,\n      scenarioIds: [id],\n      targets: [target],\n      repeatCount: 1,\n      labels: [\"cli-ephemeral\"],\n    });\n\n    spinner.text = `Running scenario against ${target.type}:${target.referenceId}...`;\n\n    const result = await suitesService.run(suite.id);\n\n    spinner.succeed(\n      `Scenario run scheduled: ${result.jobCount} job${result.jobCount !== 1 ? \"s\" : \"\"} (batch: ${result.batchRunId})`,\n    );\n\n    if (options.format === \"json\") {\n      console.log(JSON.stringify(result, null, 2));\n      await suitesService.delete(suite.id).catch(() => undefined);\n      return;\n    }\n\n    if (!options.wait) {\n      console.log();\n      console.log(`  ${chalk.gray(\"Batch Run ID:\")} ${chalk.green(result.batchRunId)}`);\n      console.log(`  ${chalk.gray(\"Suite ID:\")}     ${chalk.gray(suite.id)} ${chalk.gray(\"(ephemeral)\")}`);\n      console.log();\n      console.log(\n        chalk.gray(`View results in the LangWatch dashboard under Simulations.`),\n      );\n      console.log(\n        chalk.gray(`Or re-run with ${chalk.cyan(\"--wait\")} to poll for completion.`),\n      );\n\n      await suitesService.delete(suite.id).catch(() => undefined);\n      return;\n    }\n\n    // Poll for completion\n    console.log();\n    const pollSpinner = ora(\"Waiting for scenario run to complete...\").start();\n\n    const apiKey = process.env.LANGWATCH_API_KEY ?? \"\";\n    const endpoint = resolveControlPlaneUrl();\n\n    let completed = false;\n    const startTime = Date.now();\n    const TIMEOUT_MS = 10 * 60 * 1000;\n\n    while (!completed) {\n      if (Date.now() - startTime > TIMEOUT_MS) {\n        pollSpinner.fail(\"Scenario run timed out after 10 minutes\");\n        console.log(\n          chalk.yellow(`Check results in the dashboard. Batch ID: ${result.batchRunId}`),\n        );\n        await suitesService.delete(suite.id).catch(() => undefined);\n        process.exit(1);\n      }\n\n      await new Promise((resolve) => setTimeout(resolve, 3000));\n\n      try {\n        const statusResponse = await fetch(\n          `${endpoint}/api/scenario-events?batchRunId=${encodeURIComponent(result.batchRunId)}`,\n          {\n            method: \"GET\",\n            headers: buildAuthHeaders({ apiKey }),\n          },\n        );\n\n        if (statusResponse.ok) {\n          const statusData = await statusResponse.json() as {\n            totalCount?: number;\n            completedCount?: number;\n            passedCount?: number;\n            failedCount?: number;\n          };\n\n          const total = statusData.totalCount ?? result.jobCount;\n          const completedCount = statusData.completedCount ?? 0;\n          const passed = statusData.passedCount ?? 0;\n          const failed = statusData.failedCount ?? 0;\n\n          pollSpinner.text = `Running... ${completedCount}/${total} completed (${passed} passed, ${failed} failed)`;\n\n          if (completedCount >= total && total > 0) {\n            completed = true;\n            if (failed > 0) {\n              pollSpinner.warn(\n                `Scenario run completed: ${passed}/${total} passed, ${chalk.red(`${failed} failed`)}`,\n              );\n            } else {\n              pollSpinner.succeed(\n                `Scenario run completed: ${chalk.green(`${passed}/${total} passed`)}`,\n              );\n            }\n          }\n        }\n      } catch {\n        // Polling error — continue waiting\n      }\n    }\n\n    console.log();\n    console.log(`  ${chalk.gray(\"Batch Run ID:\")} ${chalk.green(result.batchRunId)}`);\n    console.log();\n\n    // Clean up ephemeral suite\n    await suitesService.delete(suite.id).catch(() => undefined);\n  } catch (error) {\n    failSpinner({ spinner, error, action: \"run scenario\" });\n    process.exit(1);\n  }\n};\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;AAAA,OAAO,WAAW;AAClB,OAAO,SAAS;AAUhB,SAAS,YAAY,WAAgC;AACnD,QAAM,aAAa,UAAU,QAAQ,GAAG;AACxC,MAAI,eAAe,IAAI;AACrB,YAAQ,MAAM,MAAM,IAAI,iCAAiC,SAAS,uDAAuD,CAAC;AAC1H,YAAQ,KAAK,CAAC;AAAA,EAChB;AACA,QAAM,OAAO,UAAU,MAAM,GAAG,UAAU;AAC1C,QAAM,cAAc,UAAU,MAAM,aAAa,CAAC;AAClD,MAAI,CAAC,CAAC,UAAU,QAAQ,QAAQ,UAAU,EAAE,SAAS,IAAI,GAAG;AAC1D,YAAQ,MAAM,MAAM,IAAI,+BAA+B,IAAI,iDAAiD,CAAC;AAC7G,YAAQ,KAAK,CAAC;AAAA,EAChB;AACA,SAAO,EAAE,MAAmC,YAAY;AAC1D;AAEO,IAAM,qBAAqB,OAChC,IACA,YACkB;AA7BpB;AA8BE,cAAY;AAEZ,MAAI,CAAC,QAAQ,QAAQ;AACnB,YAAQ,MAAM,MAAM,IAAI,wEAAwE,CAAC;AACjG,YAAQ,MAAM,MAAM,KAAK,mEAAmE,CAAC;AAC7F,YAAQ,MAAM,MAAM,KAAK,8CAA8C,CAAC;AACxE,YAAQ,KAAK,CAAC;AAAA,EAChB;AAEA,QAAM,SAAS,YAAY,QAAQ,MAAM;AACzC,QAAM,gBAAgB,IAAI,iBAAiB;AAG3C,QAAM,UAAU,IAAI,+BAA+B,EAAE,MAAM,EAAE,MAAM;AAEnE,MAAI;AAEF,UAAM,QAAQ,MAAM,cAAc,OAAO;AAAA,MACvC,MAAM,qBAAqB,EAAE;AAAA,MAC7B,aAAa,uDAAuD,EAAE;AAAA,MACtE,aAAa,CAAC,EAAE;AAAA,MAChB,SAAS,CAAC,MAAM;AAAA,MAChB,aAAa;AAAA,MACb,QAAQ,CAAC,eAAe;AAAA,IAC1B,CAAC;AAED,YAAQ,OAAO,4BAA4B,OAAO,IAAI,IAAI,OAAO,WAAW;AAE5E,UAAM,SAAS,MAAM,cAAc,IAAI,MAAM,EAAE;AAE/C,YAAQ;AAAA,MACN,2BAA2B,OAAO,QAAQ,OAAO,OAAO,aAAa,IAAI,MAAM,EAAE,YAAY,OAAO,UAAU;AAAA,IAChH;AAEA,QAAI,QAAQ,WAAW,QAAQ;AAC7B,cAAQ,IAAI,KAAK,UAAU,QAAQ,MAAM,CAAC,CAAC;AAC3C,YAAM,cAAc,OAAO,MAAM,EAAE,EAAE,MAAM,MAAM,MAAS;AAC1D;AAAA,IACF;AAEA,QAAI,CAAC,QAAQ,MAAM;AACjB,cAAQ,IAAI;AACZ,cAAQ,IAAI,KAAK,MAAM,KAAK,eAAe,CAAC,IAAI,MAAM,MAAM,OAAO,UAAU,CAAC,EAAE;AAChF,cAAQ,IAAI,KAAK,MAAM,KAAK,WAAW,CAAC,QAAQ,MAAM,KAAK,MAAM,EAAE,CAAC,IAAI,MAAM,KAAK,aAAa,CAAC,EAAE;AACnG,cAAQ,IAAI;AACZ,cAAQ;AAAA,QACN,MAAM,KAAK,4DAA4D;AAAA,MACzE;AACA,cAAQ;AAAA,QACN,MAAM,KAAK,kBAAkB,MAAM,KAAK,QAAQ,CAAC,0BAA0B;AAAA,MAC7E;AAEA,YAAM,cAAc,OAAO,MAAM,EAAE,EAAE,MAAM,MAAM,MAAS;AAC1D;AAAA,IACF;AAGA,YAAQ,IAAI;AACZ,UAAM,cAAc,IAAI,yCAAyC,EAAE,MAAM;AAEzE,UAAM,UAAS,aAAQ,IAAI,sBAAZ,YAAiC;AAChD,UAAM,WAAW,uBAAuB;AAExC,QAAI,YAAY;AAChB,UAAM,YAAY,KAAK,IAAI;AAC3B,UAAM,aAAa,KAAK,KAAK;AAE7B,WAAO,CAAC,WAAW;AACjB,UAAI,KAAK,IAAI,IAAI,YAAY,YAAY;AACvC,oBAAY,KAAK,yCAAyC;AAC1D,gBAAQ;AAAA,UACN,MAAM,OAAO,6CAA6C,OAAO,UAAU,EAAE;AAAA,QAC/E;AACA,cAAM,cAAc,OAAO,MAAM,EAAE,EAAE,MAAM,MAAM,MAAS;AAC1D,gBAAQ,KAAK,CAAC;AAAA,MAChB;AAEA,YAAM,IAAI,QAAQ,CAAC,YAAY,WAAW,SAAS,GAAI,CAAC;AAExD,UAAI;AACF,cAAM,iBAAiB,MAAM;AAAA,UAC3B,GAAG,QAAQ,mCAAmC,mBAAmB,OAAO,UAAU,CAAC;AAAA,UACnF;AAAA,YACE,QAAQ;AAAA,YACR,SAAS,iBAAiB,EAAE,OAAO,CAAC;AAAA,UACtC;AAAA,QACF;AAEA,YAAI,eAAe,IAAI;AACrB,gBAAM,aAAa,MAAM,eAAe,KAAK;AAO7C,gBAAM,SAAQ,gBAAW,eAAX,YAAyB,OAAO;AAC9C,gBAAM,kBAAiB,gBAAW,mBAAX,YAA6B;AACpD,gBAAM,UAAS,gBAAW,gBAAX,YAA0B;AACzC,gBAAM,UAAS,gBAAW,gBAAX,YAA0B;AAEzC,sBAAY,OAAO,cAAc,cAAc,IAAI,KAAK,eAAe,MAAM,YAAY,MAAM;AAE/F,cAAI,kBAAkB,SAAS,QAAQ,GAAG;AACxC,wBAAY;AACZ,gBAAI,SAAS,GAAG;AACd,0BAAY;AAAA,gBACV,2BAA2B,MAAM,IAAI,KAAK,YAAY,MAAM,IAAI,GAAG,MAAM,SAAS,CAAC;AAAA,cACrF;AAAA,YACF,OAAO;AACL,0BAAY;AAAA,gBACV,2BAA2B,MAAM,MAAM,GAAG,MAAM,IAAI,KAAK,SAAS,CAAC;AAAA,cACrE;AAAA,YACF;AAAA,UACF;AAAA,QACF;AAAA,MACF,SAAQ;AAAA,MAER;AAAA,IACF;AAEA,YAAQ,IAAI;AACZ,YAAQ,IAAI,KAAK,MAAM,KAAK,eAAe,CAAC,IAAI,MAAM,MAAM,OAAO,UAAU,CAAC,EAAE;AAChF,YAAQ,IAAI;AAGZ,UAAM,cAAc,OAAO,MAAM,EAAE,EAAE,MAAM,MAAM,MAAS;AAAA,EAC5D,SAAS,OAAO;AACd,gBAAY,EAAE,SAAS,OAAO,QAAQ,eAAe,CAAC;AACtD,YAAQ,KAAK,CAAC;AAAA,EAChB;AACF;","names":[]}