deepline 0.1.174 → 0.1.176

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/cli/index.js CHANGED
@@ -622,10 +622,10 @@ var SDK_RELEASE = {
622
622
  // 0.1.111 ships dataset-native tool list getters and result row datasets.
623
623
  // 0.1.154 removes the short-lived generated enrich StepOptions recompute
624
624
  // fields shipped in 0.1.153.
625
- version: "0.1.174",
625
+ version: "0.1.176",
626
626
  apiContract: "2026-06-dataset-handle-results-hard-cutover",
627
627
  supportPolicy: {
628
- latest: "0.1.174",
628
+ latest: "0.1.176",
629
629
  minimumSupported: "0.1.53",
630
630
  deprecatedBelow: "0.1.53",
631
631
  commandMinimumSupported: [
@@ -886,9 +886,10 @@ var HttpClient = class {
886
886
  headers["Content-Type"] = "application/json";
887
887
  }
888
888
  let lastError = null;
889
- const candidateUrls = buildCandidateUrls(url);
889
+ const candidateUrls = options?.exactUrlOnly ? [url] : buildCandidateUrls(url);
890
890
  let retryAfterDelayMs = null;
891
- for (let attempt = 0; attempt <= this.config.maxRetries; attempt++) {
891
+ const maxRetries = options?.maxRetries ?? this.config.maxRetries;
892
+ for (let attempt = 0; attempt <= maxRetries; attempt++) {
892
893
  if (attempt > 0) {
893
894
  const backoffMs = Math.min(1e3 * Math.pow(2, attempt - 1), 3e4);
894
895
  const delayMs = retryAfterDelayMs === null ? backoffMs : Math.max(backoffMs, retryAfterDelayMs);
@@ -915,7 +916,7 @@ var HttpClient = class {
915
916
  if (response.status === 429) {
916
917
  const retryAfter = parseRetryAfter(response);
917
918
  lastError = new RateLimitError(retryAfter);
918
- if (attempt < this.config.maxRetries) {
919
+ if (attempt < maxRetries) {
919
920
  retryAfterDelayMs = retryAfter;
920
921
  break;
921
922
  }
@@ -945,7 +946,7 @@ var HttpClient = class {
945
946
  ...htmlError.workerThrewException ? { workerThrewException: true } : {}
946
947
  }
947
948
  );
948
- if (retryableApiError && attempt < this.config.maxRetries) {
949
+ if (retryableApiError && attempt < maxRetries) {
949
950
  retryAfterDelayMs = parseOptionalRetryAfter(response);
950
951
  break;
951
952
  }
@@ -957,7 +958,7 @@ var HttpClient = class {
957
958
  lastError = new DeeplineError(msg, response.status, apiErrorCode, {
958
959
  response: parsed
959
960
  });
960
- if (retryableApiError && attempt < this.config.maxRetries) {
961
+ if (retryableApiError && attempt < maxRetries) {
961
962
  retryAfterDelayMs = parseOptionalRetryAfter(response);
962
963
  break;
963
964
  }
@@ -976,7 +977,7 @@ var HttpClient = class {
976
977
  lastError = error instanceof Error ? error : new Error(String(error));
977
978
  }
978
979
  }
979
- if (attempt < this.config.maxRetries) continue;
980
+ if (attempt < maxRetries) continue;
980
981
  }
981
982
  if (lastError instanceof DeeplineError) {
982
983
  throw lastError;
@@ -2111,6 +2112,7 @@ var COMPILE_MANIFEST_RETRY_DELAYS_MS = [250, 1e3];
2111
2112
  var REGISTER_PLAY_ARTIFACTS_COMPILE_CONCURRENCY = 3;
2112
2113
  var REGISTER_PLAY_ARTIFACTS_MAX_BATCH_COUNT = 3;
2113
2114
  var REGISTER_PLAY_ARTIFACTS_MAX_BATCH_BYTES = 25e5;
2115
+ var DEEPLINEAGENT_EXECUTE_TIMEOUT_MS = 15 * 60 * 1e3;
2114
2116
  function normalizePlayRunIntegrationMode(value) {
2115
2117
  if (value === "live" || value === "eval_stub" || value === "fixture") {
2116
2118
  return value;
@@ -2185,6 +2187,10 @@ function chunkRegisterPlayArtifacts(artifacts) {
2185
2187
  }
2186
2188
  return chunks;
2187
2189
  }
2190
+ function resolveToolExecuteTimeoutMs(toolId) {
2191
+ const normalized = toolId.trim().toLowerCase();
2192
+ return normalized === "deeplineagent" || normalized === "deeplineagent_deeplineagent" || normalized === "ai_inference" || normalized === "deeplineagent_ai_inference" || normalized === "aiinference" ? DEEPLINEAGENT_EXECUTE_TIMEOUT_MS : void 0;
2193
+ }
2188
2194
  var RUN_LOGS_PAGE_LIMIT = 1e3;
2189
2195
  function isRecord3(value) {
2190
2196
  return Boolean(value && typeof value === "object" && !Array.isArray(value));
@@ -2624,7 +2630,12 @@ var DeeplineClient = class {
2624
2630
  `/api/v2/integrations/${encodeURIComponent(toolId)}/execute`,
2625
2631
  { payload: input2 },
2626
2632
  headers,
2627
- { forbiddenAsApiError: true }
2633
+ {
2634
+ forbiddenAsApiError: true,
2635
+ timeout: options?.timeout ?? resolveToolExecuteTimeoutMs(toolId),
2636
+ maxRetries: options?.maxRetries ?? 0,
2637
+ exactUrlOnly: true
2638
+ }
2628
2639
  );
2629
2640
  }
2630
2641
  /**
@@ -2686,6 +2697,7 @@ var DeeplineClient = class {
2686
2697
  */
2687
2698
  async startPlayRun(request) {
2688
2699
  const integrationMode = resolvePlayRunIntegrationMode(request);
2700
+ const forceToolRefresh = request.forceToolRefresh === true;
2689
2701
  const response = await this.http.post(
2690
2702
  "/api/v2/plays/run",
2691
2703
  {
@@ -2706,6 +2718,7 @@ var DeeplineClient = class {
2706
2718
  ...request.inputFile ? { inputFile: request.inputFile } : {},
2707
2719
  ...request.packagedFiles?.length ? { packagedFiles: request.packagedFiles } : {},
2708
2720
  ...request.force ? { force: true } : {},
2721
+ ...forceToolRefresh ? { forceToolRefresh: true } : {},
2709
2722
  ...typeof request.waitForCompletionMs === "number" ? { waitForCompletionMs: request.waitForCompletionMs } : {},
2710
2723
  // Profile selection is the API's job, not the CLI's. The server
2711
2724
  // defaults to workers_edge; tests and runtime probes that want a
@@ -2729,6 +2742,7 @@ var DeeplineClient = class {
2729
2742
  */
2730
2743
  async *startPlayRunStream(request, options) {
2731
2744
  const integrationMode = resolvePlayRunIntegrationMode(request);
2745
+ const forceToolRefresh = request.forceToolRefresh === true;
2732
2746
  const body = {
2733
2747
  ...request.name ? { name: request.name } : {},
2734
2748
  ...request.revisionId ? { revisionId: request.revisionId } : {},
@@ -2747,6 +2761,7 @@ var DeeplineClient = class {
2747
2761
  ...request.inputFile ? { inputFile: request.inputFile } : {},
2748
2762
  ...request.packagedFiles?.length ? { packagedFiles: request.packagedFiles } : {},
2749
2763
  ...request.force ? { force: true } : {},
2764
+ ...forceToolRefresh ? { forceToolRefresh: true } : {},
2750
2765
  ...typeof request.waitForCompletionMs === "number" ? { waitForCompletionMs: request.waitForCompletionMs } : {},
2751
2766
  ...request.profile ? { profile: request.profile } : {},
2752
2767
  ...integrationMode ? { integrationMode } : {}
@@ -2918,7 +2933,8 @@ var DeeplineClient = class {
2918
2933
  ...input2.input ? { input: input2.input } : {},
2919
2934
  ...input2.inputFile ? { inputFile: input2.inputFile } : {},
2920
2935
  ...input2.packagedFiles?.length ? { packagedFiles: input2.packagedFiles } : {},
2921
- ...input2.force ? { force: true } : {}
2936
+ ...input2.force ? { force: true } : {},
2937
+ ...input2.forceToolRefresh ? { forceToolRefresh: true } : {}
2922
2938
  });
2923
2939
  }
2924
2940
  /**
@@ -2991,7 +3007,8 @@ var DeeplineClient = class {
2991
3007
  ...Object.keys(runtimeInput).length > 0 ? { input: runtimeInput } : {},
2992
3008
  ...options?.inputFile ? { inputFile: options.inputFile } : {},
2993
3009
  ...options?.packagedFiles?.length ? { packagedFiles: options.packagedFiles } : {},
2994
- ...options?.force ? { force: true } : {}
3010
+ ...options?.force ? { force: true } : {},
3011
+ ...options?.forceToolRefresh ? { forceToolRefresh: true } : {}
2995
3012
  });
2996
3013
  }
2997
3014
  /**
@@ -3873,7 +3890,8 @@ var DeeplineClient = class {
3873
3890
  compilerManifest: options?.compilerManifest,
3874
3891
  inputFile: options?.inputFile,
3875
3892
  packagedFiles: options?.packagedFiles,
3876
- force: options?.force
3893
+ force: options?.force,
3894
+ forceToolRefresh: options?.forceToolRefresh
3877
3895
  });
3878
3896
  const start = Date.now();
3879
3897
  const state = {
@@ -4565,10 +4583,21 @@ function failureMessageFromRecord(value) {
4565
4583
  }
4566
4584
  return directError || resultError || `Column status: ${status}`;
4567
4585
  }
4568
- function flattenObjectColumns(row) {
4586
+ function shouldPreserveJsonStringColumn(columns, key) {
4587
+ if (!columns) {
4588
+ return false;
4589
+ }
4590
+ if (columns.has(key)) {
4591
+ return true;
4592
+ }
4593
+ const normalizedKey = key.toLowerCase().replace(/[^a-z0-9]/g, "");
4594
+ return normalizedKey ? columns.has(normalizedKey) : false;
4595
+ }
4596
+ function flattenObjectColumns(row, options = {}) {
4569
4597
  const flattened = {};
4570
4598
  for (const [key, rawValue] of Object.entries(row)) {
4571
4599
  const value = parseMaybeJsonObject(rawValue);
4600
+ const parsedFromString = typeof rawValue === "string" && value !== rawValue;
4572
4601
  if (key === "_metadata") {
4573
4602
  flattened[key] = value && typeof value === "object" ? JSON.stringify(value) : value;
4574
4603
  continue;
@@ -4579,6 +4608,10 @@ function flattenObjectColumns(row) {
4579
4608
  if (hasMatchedEnvelope) {
4580
4609
  flattened[key] = JSON.stringify(record);
4581
4610
  continue;
4611
+ }
4612
+ if (parsedFromString && shouldPreserveJsonStringColumn(options.preserveJsonStringColumns, key)) {
4613
+ flattened[key] = rawValue;
4614
+ continue;
4582
4615
  } else {
4583
4616
  const failureMessage = failureMessageFromRecord(record);
4584
4617
  if (failureMessage) {
@@ -4603,8 +4636,8 @@ function recordRows(value) {
4603
4636
  (row) => Boolean(row) && typeof row === "object" && !Array.isArray(row)
4604
4637
  );
4605
4638
  }
4606
- function dataExportRows(rows) {
4607
- return rows.map((row) => flattenObjectColumns(row));
4639
+ function dataExportRows(rows, options = {}) {
4640
+ return rows.map((row) => flattenObjectColumns(row, options));
4608
4641
  }
4609
4642
  function dataExportColumns(rows, preferredColumns = []) {
4610
4643
  const discoveredColumns = [
@@ -13357,7 +13390,7 @@ async function handleFileBackedRun(options) {
13357
13390
  ...Object.keys(runtimeInput).length > 0 ? { input: runtimeInput } : {},
13358
13391
  ...stagedFileInputs.inputFile ? { inputFile: stagedFileInputs.inputFile } : {},
13359
13392
  ...stagedFileInputs.packagedFiles.length ? { packagedFiles: stagedFileInputs.packagedFiles } : {},
13360
- ...options.force ? { force: true } : {},
13393
+ ...options.force ? { force: true, forceToolRefresh: true } : {},
13361
13394
  ...options.profile ? { profile: options.profile } : {},
13362
13395
  ...integrationMode ? { integrationMode } : {}
13363
13396
  };
@@ -13516,7 +13549,7 @@ async function handleNamedRun(options) {
13516
13549
  ...Object.keys(runtimeInput).length > 0 ? { input: runtimeInput } : {},
13517
13550
  ...stagedFileInputs.inputFile ? { inputFile: stagedFileInputs.inputFile } : {},
13518
13551
  ...stagedFileInputs.packagedFiles.length ? { packagedFiles: stagedFileInputs.packagedFiles } : {},
13519
- ...options.force ? { force: true } : {},
13552
+ ...options.force ? { force: true, forceToolRefresh: true } : {},
13520
13553
  ...options.profile ? { profile: options.profile } : {},
13521
13554
  ...integrationMode ? { integrationMode } : {}
13522
13555
  };
@@ -14702,9 +14735,9 @@ Notes:
14702
14735
  a fire-and-forget run id.
14703
14736
  The play page opens in your browser as soon as the run starts; use --no-open
14704
14737
  to only print the URL.
14705
- Concurrent runs for the same play are allowed. --force is accepted for
14706
- compatibility, but it does not cancel active sibling runs or bypass completed
14707
- reuse.
14738
+ Concurrent runs for the same play are allowed.
14739
+ --force bypasses durable dataset/tool cache reuse for this run.
14740
+ It does not cancel active sibling runs.
14708
14741
  This command starts cloud work and may spend Deepline credits through tool calls.
14709
14742
 
14710
14743
  Idempotent execution:
@@ -14755,7 +14788,7 @@ Examples:
14755
14788
  ).option("--watch", "Compatibility alias; run waits by default").option("--wait", "Compatibility alias; run waits by default").option("--no-wait", "Start the run and return immediately").option(
14756
14789
  "--logs",
14757
14790
  "When output is non-interactive, stream play logs to stderr while waiting"
14758
- ).option("--tail-timeout-ms <ms>", "Timeout while watching the run stream").option("--force", "Compatibility flag; active sibling runs are allowed").option("--no-open", "Print the play page URL without opening a browser").option("--json", "Emit JSON output").option("--full", "Debug only: with --json, emit the raw status payload").addHelpText(
14791
+ ).option("--tail-timeout-ms <ms>", "Timeout while watching the run stream").option("--force", "Bypass durable dataset/tool cache reuse").option("--no-open", "Print the play page URL without opening a browser").option("--json", "Emit JSON output").option("--full", "Debug only: with --json, emit the raw status payload").addHelpText(
14759
14792
  "afterAll",
14760
14793
  `
14761
14794
  Pass-through input flags:
@@ -16876,7 +16909,8 @@ function helperSource() {
16876
16909
  // src/cli/commands/enrich.ts
16877
16910
  var ENRICH_EXPORT_PAGE_SIZE = 5e3;
16878
16911
  var ENRICH_AUTO_BATCH_ROWS = 250;
16879
- var ENRICH_HEAVY_PLAY_AUTO_BATCH_ROWS = 40;
16912
+ var ENRICH_HEAVY_PLAY_AUTO_BATCH_ROWS = 25;
16913
+ var ENRICH_NESTED_PROVIDER_AUTO_BATCH_ROWS = 50;
16880
16914
  var ENRICH_EXPORT_BACKING_ROWS_WAIT_MS = 6e4;
16881
16915
  var ENRICH_EXPORT_BACKING_ROWS_POLL_MS = 1e3;
16882
16916
  var ENRICH_SOURCE_ROW_INDEX_COLUMN = "__deeplineSourceRowIndex";
@@ -16891,6 +16925,12 @@ var HEAVY_ENRICH_AUTO_BATCH_PLAYS = /* @__PURE__ */ new Set([
16891
16925
  "company-to-contact-by-role-waterfall",
16892
16926
  "company_to_contact_by_role_waterfall"
16893
16927
  ]);
16928
+ var HEAVY_ENRICH_AUTO_BATCH_TOOLS = /* @__PURE__ */ new Set([
16929
+ "ai_inference",
16930
+ "aiinference",
16931
+ "deeplineagent"
16932
+ ]);
16933
+ var ENRICH_TEST_AI_INFERENCE_PAYLOAD_MARKER = "__deeplineTestAiInference";
16894
16934
  var PLAN_SHAPING_OPTION_NAMES = [
16895
16935
  "with",
16896
16936
  "withWaterfall",
@@ -16908,6 +16948,15 @@ function normalizeAlias2(value) {
16908
16948
  function hasPlanShapingArgs(args) {
16909
16949
  return optionWasProvided(args, "--with") || optionWasProvided(args, "--with-waterfall") || optionWasProvided(args, "--min-results") || optionWasProvided(args, "--end-waterfall");
16910
16950
  }
16951
+ function isMarkedTestAiInferenceCommand(command) {
16952
+ if ("with_waterfall" in command) {
16953
+ return false;
16954
+ }
16955
+ if (normalizeEnrichPlayRef(command.tool) !== "run_javascript") {
16956
+ return false;
16957
+ }
16958
+ return isRecord7(command.payload) && command.payload[ENRICH_TEST_AI_INFERENCE_PAYLOAD_MARKER] === true;
16959
+ }
16911
16960
  function enrichDebugEnabled(env = process.env) {
16912
16961
  const raw = String(env.DEEPLINE_DEBUG_ENRICH ?? "").trim().toLowerCase();
16913
16962
  if (["1", "true", "yes", "on"].includes(raw)) {
@@ -17675,8 +17724,6 @@ function normalizeEnrichPlayRef(value) {
17675
17724
  return normalized || null;
17676
17725
  }
17677
17726
  function configContainsHeavyEnrichPlay(config) {
17678
- let hasNestedPlayStep = false;
17679
- let hasSubrequestProviderStep = false;
17680
17727
  const visit = (commands) => {
17681
17728
  for (const command of commands) {
17682
17729
  if ("with_waterfall" in command) {
@@ -17700,18 +17747,67 @@ function configContainsHeavyEnrichPlay(config) {
17700
17747
  return true;
17701
17748
  }
17702
17749
  const normalizedTool = normalizeEnrichPlayRef(command.tool);
17750
+ const normalizedOperation = normalizeEnrichPlayRef(command.operation);
17751
+ if (isMarkedTestAiInferenceCommand(command) || normalizedTool && HEAVY_ENRICH_AUTO_BATCH_TOOLS.has(normalizedTool) || normalizedOperation && HEAVY_ENRICH_AUTO_BATCH_TOOLS.has(normalizedOperation)) {
17752
+ return true;
17753
+ }
17754
+ }
17755
+ return false;
17756
+ };
17757
+ return visit(config.commands);
17758
+ }
17759
+ function configContainsNestedProviderEnrichWorkload(config) {
17760
+ let hasNestedPlayStep = false;
17761
+ let hasSubrequestProviderStep = false;
17762
+ const visit = (commands) => {
17763
+ for (const command of commands) {
17764
+ if ("with_waterfall" in command) {
17765
+ visit(command.commands);
17766
+ continue;
17767
+ }
17768
+ if (command.disabled) {
17769
+ continue;
17770
+ }
17771
+ const normalizedTool = normalizeEnrichPlayRef(command.tool);
17703
17772
  if (command.play || normalizedTool === "test-play") {
17704
17773
  hasNestedPlayStep = true;
17705
17774
  } else if (normalizedTool !== null && normalizedTool !== "run_javascript") {
17706
17775
  hasSubrequestProviderStep = true;
17707
17776
  }
17708
17777
  }
17709
- return false;
17710
17778
  };
17711
- return visit(config.commands) || hasNestedPlayStep && hasSubrequestProviderStep;
17779
+ visit(config.commands);
17780
+ return hasNestedPlayStep && hasSubrequestProviderStep;
17712
17781
  }
17713
17782
  function enrichAutoBatchRowsForConfig(config) {
17714
- return configContainsHeavyEnrichPlay(config) ? ENRICH_HEAVY_PLAY_AUTO_BATCH_ROWS : ENRICH_AUTO_BATCH_ROWS;
17783
+ if (configContainsHeavyEnrichPlay(config)) {
17784
+ return ENRICH_HEAVY_PLAY_AUTO_BATCH_ROWS;
17785
+ }
17786
+ if (configContainsNestedProviderEnrichWorkload(config)) {
17787
+ return ENRICH_NESTED_PROVIDER_AUTO_BATCH_ROWS;
17788
+ }
17789
+ return ENRICH_AUTO_BATCH_ROWS;
17790
+ }
17791
+ function enrichAiRuntimeCompactAliases(config) {
17792
+ const aliases = /* @__PURE__ */ new Set();
17793
+ const visit = (commands) => {
17794
+ for (const command of commands) {
17795
+ if ("with_waterfall" in command) {
17796
+ visit(command.commands);
17797
+ continue;
17798
+ }
17799
+ if (command.disabled) {
17800
+ continue;
17801
+ }
17802
+ const normalizedTool = normalizeEnrichPlayRef(command.tool);
17803
+ const normalizedOperation = normalizeEnrichPlayRef(command.operation);
17804
+ if (isMarkedTestAiInferenceCommand(command) || normalizedTool && HEAVY_ENRICH_AUTO_BATCH_TOOLS.has(normalizedTool) || normalizedOperation && HEAVY_ENRICH_AUTO_BATCH_TOOLS.has(normalizedOperation)) {
17805
+ aliases.add(normalizeAlias2(command.alias));
17806
+ }
17807
+ }
17808
+ };
17809
+ visit(config.commands);
17810
+ return aliases;
17715
17811
  }
17716
17812
  async function maybeWriteOutputCsv(input2) {
17717
17813
  if (!input2.outputPath) return null;
@@ -17807,6 +17903,52 @@ function selectedSourceCsvRange(sourceCsvPath, rows) {
17807
17903
  sourceRows
17808
17904
  };
17809
17905
  }
17906
+ function compactRuntimeCsvCell(value) {
17907
+ const parsed = parseMaybeJsonObject(value);
17908
+ const compacted = compactAiInferenceCellForCsv(parsed);
17909
+ return materializeCsvCellValue(compacted);
17910
+ }
17911
+ async function writeSlimBatchedRuntimeCsv(input2) {
17912
+ const cleanRows = readCsvRows(input2.cleanSourceCsvPath).map(
17913
+ (row) => ({ ...row })
17914
+ );
17915
+ const mergeRows = readCsvRows(input2.mergeSourceCsvPath);
17916
+ const preserveJsonStringColumns = /* @__PURE__ */ new Set([
17917
+ ...cleanRows.flatMap((row) => Object.keys(row)),
17918
+ ...mergeRows.flatMap((row) => Object.keys(row))
17919
+ ]);
17920
+ const selectedRange = selectedSourceCsvRange(
17921
+ input2.mergeSourceCsvPath,
17922
+ input2.rows
17923
+ );
17924
+ for (let rowIndex = selectedRange.start; rowIndex <= selectedRange.end; rowIndex += 1) {
17925
+ const mergeRow = mergeRows[rowIndex];
17926
+ if (!mergeRow) {
17927
+ continue;
17928
+ }
17929
+ const baseRow = cleanRows[rowIndex] ?? {};
17930
+ const compactOverlayCell = ([key, value]) => {
17931
+ return [
17932
+ key,
17933
+ input2.compactAliases.has(normalizeAlias2(key)) ? compactRuntimeCsvCell(value) : value
17934
+ ];
17935
+ };
17936
+ cleanRows[rowIndex] = {
17937
+ ...baseRow,
17938
+ ...Object.fromEntries(
17939
+ Object.entries(mergeRow).map(compactOverlayCell)
17940
+ )
17941
+ };
17942
+ }
17943
+ const columns = dataExportColumns(
17944
+ dataExportRows(cleanRows, { preserveJsonStringColumns })
17945
+ );
17946
+ await (0, import_promises3.writeFile)(
17947
+ input2.outputPath,
17948
+ csvStringFromRows(cleanRows, columns),
17949
+ "utf8"
17950
+ );
17951
+ }
17810
17952
  function selectedSourceCsvRowCount(options) {
17811
17953
  if (!options?.sourceCsvPath) {
17812
17954
  return null;
@@ -18113,6 +18255,22 @@ function mergeExportedSheetRow(target, next) {
18113
18255
  target._metadata = metadata;
18114
18256
  }
18115
18257
  }
18258
+ function countEnrichedRowsInSourceRange(exportResult, rows) {
18259
+ const start = Math.max(0, rows.rowStart ?? 0);
18260
+ const end = rows.rowEnd === null || rows.rowEnd === void 0 ? Number.MAX_SAFE_INTEGER : Math.max(start, rows.rowEnd);
18261
+ const rowIndexes = /* @__PURE__ */ new Set();
18262
+ for (const row of exportResult.enrichedDataRows) {
18263
+ const rowIndex = sourceRowIndexFromEnrichRow(row, start, end);
18264
+ if (rowIndex !== null) {
18265
+ rowIndexes.add(rowIndex);
18266
+ }
18267
+ }
18268
+ if (rowIndexes.size > 0) {
18269
+ return rowIndexes.size;
18270
+ }
18271
+ const selectedRows = end === Number.MAX_SAFE_INTEGER ? exportResult.enrichedRows : end - start + 1;
18272
+ return Math.min(exportResult.enrichedRows, Math.max(0, selectedRows));
18273
+ }
18116
18274
  function coalesceExportableSheetRows(rows, sourceRowStart = 0) {
18117
18275
  const mergedRows = [];
18118
18276
  const bySourceRowIndex = /* @__PURE__ */ new Map();
@@ -18744,10 +18902,12 @@ async function fetchBackingRowsForCsvExport(input2) {
18744
18902
  };
18745
18903
  }
18746
18904
  function mergeRowsForCsvExport(enrichedRows, options) {
18905
+ const compactAliases = options?.config ? enrichAiRuntimeCompactAliases(options.config) : /* @__PURE__ */ new Set();
18747
18906
  const rows = dataExportRows(
18748
18907
  normalizeEnrichRowsForCsvExport(enrichedRows, options?.config, {
18749
18908
  statusFailureMessages: options?.statusFailureMessages
18750
- })
18909
+ }),
18910
+ { preserveJsonStringColumns: compactAliases }
18751
18911
  );
18752
18912
  const range = options?.rows;
18753
18913
  if (!options?.sourceCsvPath) {
@@ -18767,16 +18927,16 @@ function mergeRowsForCsvExport(enrichedRows, options) {
18767
18927
  const maxEnd = Math.max(start, baseRows.length - 1);
18768
18928
  const inclusiveEnd = range?.rowEnd === null || range?.rowEnd === void 0 ? maxEnd : Math.min(maxEnd, range.rowEnd);
18769
18929
  const expectedSelectedRows = baseRows.length === 0 ? 0 : Math.max(0, inclusiveEnd - start + 1);
18770
- const canMergeSparseBySourceIndex = rows.length > 0 && rows.every(
18930
+ const hasRowsInSelectedRange = rows.some(
18771
18931
  (row) => sourceRowIndexFromEnrichRow(row, start, inclusiveEnd) !== null
18772
18932
  );
18773
- if (options.inPlace && rows.length < expectedSelectedRows && !options.allowPartial && !canMergeSparseBySourceIndex) {
18933
+ if (options.inPlace && rows.length < expectedSelectedRows && !options.allowPartial && !hasRowsInSelectedRange) {
18774
18934
  throw new Error(
18775
18935
  `Refusing to write a partial in-place CSV export: the run returned ${rows.length} row(s) for ${expectedSelectedRows} selected source row(s).`
18776
18936
  );
18777
18937
  }
18778
18938
  const merged = [...baseRows];
18779
- if (canMergeSparseBySourceIndex) {
18939
+ if (hasRowsInSelectedRange) {
18780
18940
  for (const rawEnriched of rows) {
18781
18941
  const rowIndex = sourceRowIndexFromEnrichRow(
18782
18942
  rawEnriched,
@@ -18911,9 +19071,45 @@ function materializeCsvCellValue(value) {
18911
19071
  }
18912
19072
  return value;
18913
19073
  }
18914
- function materializeAliasSuccessCell(row, alias) {
19074
+ function disambiguateCompactAiInferencePayload(value) {
19075
+ const parsed = parseMaybeJsonObject(value);
19076
+ if (!isRecord7(parsed) || !cellFailureError(parsed)) {
19077
+ return value;
19078
+ }
19079
+ return {
19080
+ status: "completed",
19081
+ extracted_json: parsed
19082
+ };
19083
+ }
19084
+ function compactAiInferenceCellForCsv(value) {
19085
+ if (!isRecord7(value)) {
19086
+ return value;
19087
+ }
19088
+ const extractedJson = value.extracted_json;
19089
+ if (extractedJson !== null && extractedJson !== void 0) {
19090
+ return disambiguateCompactAiInferencePayload(extractedJson);
19091
+ }
19092
+ const result = isRecord7(value.result) ? value.result : null;
19093
+ const object = result?.object;
19094
+ if (object !== null && object !== void 0) {
19095
+ return disambiguateCompactAiInferencePayload(object);
19096
+ }
19097
+ const text = result?.text;
19098
+ if (typeof text === "string" && text.trim()) {
19099
+ return disambiguateCompactAiInferencePayload(text);
19100
+ }
19101
+ const output2 = value.output;
19102
+ if (typeof output2 === "string" && output2.trim()) {
19103
+ return disambiguateCompactAiInferencePayload(output2);
19104
+ }
19105
+ return value;
19106
+ }
19107
+ function materializeEnrichAliasCellForCsv(row, alias, options) {
18915
19108
  const direct = row[alias];
18916
19109
  if (isRecord7(direct)) {
19110
+ if (options?.compactAiCell && direct.status === "completed" && (isRecord7(direct.result) || Object.prototype.hasOwnProperty.call(direct, "extracted_json") || typeof direct.output === "string")) {
19111
+ return materializeCsvCellValue(compactAiInferenceCellForCsv(direct));
19112
+ }
18917
19113
  if (Object.prototype.hasOwnProperty.call(direct, "matched_result") || Object.prototype.hasOwnProperty.call(direct, "matchedResult") || Object.prototype.hasOwnProperty.call(direct, "result")) {
18918
19114
  return materializeCsvCellValue(direct);
18919
19115
  }
@@ -18972,6 +19168,7 @@ function materializeAliasSuccessCell(row, alias) {
18972
19168
  }
18973
19169
  function normalizeEnrichRowsForCsvExport(rows, config, options) {
18974
19170
  const aliases = config ? collectConfigScalarAliasOrder(config) : [];
19171
+ const aiCompactAliases = config ? enrichAiRuntimeCompactAliases(config) : null;
18975
19172
  const failureOperationByAlias = hardFailureOperationByAlias(config);
18976
19173
  return rows.map((row) => {
18977
19174
  const metadata = legacyMetadataFromRow(row);
@@ -19014,7 +19211,9 @@ function normalizeEnrichRowsForCsvExport(rows, config, options) {
19014
19211
  }
19015
19212
  }
19016
19213
  for (const alias of aliases) {
19017
- const value = materializeAliasSuccessCell(normalized, alias);
19214
+ const value = materializeEnrichAliasCellForCsv(normalized, alias, {
19215
+ compactAiCell: aiCompactAliases?.has(normalizeAlias2(alias)) ?? false
19216
+ });
19018
19217
  if (value !== void 0) {
19019
19218
  normalized[alias] = value;
19020
19219
  continue;
@@ -19339,7 +19538,7 @@ function registerEnrichCommand(program) {
19339
19538
  capturedResult: captured2.result,
19340
19539
  client: client2,
19341
19540
  config,
19342
- sourceCsvPath: input2.sourceCsvPath,
19541
+ sourceCsvPath: input2.mergeSourceCsvPath ?? input2.sourceCsvPath,
19343
19542
  rows: input2.rows,
19344
19543
  inPlace: Boolean(options.inPlace)
19345
19544
  });
@@ -19355,11 +19554,12 @@ function registerEnrichCommand(program) {
19355
19554
  `
19356
19555
  );
19357
19556
  }
19358
- let workingSourceCsvPath = sourceCsvPath;
19557
+ let workingMergeSourceCsvPath = sourceCsvPath;
19359
19558
  let lastStatus = null;
19360
19559
  let finalExportResult = null;
19361
19560
  let totalEnrichedRows = 0;
19362
19561
  const batchFailureRows = [];
19562
+ const runtimeCompactAliases = enrichAiRuntimeCompactAliases(config);
19363
19563
  for (let chunkStart = selectedRange.start, chunkIndex = 0; chunkStart <= selectedRange.end; chunkStart += autoBatchRows, chunkIndex += 1) {
19364
19564
  const chunkRows = {
19365
19565
  rowStart: chunkStart,
@@ -19374,8 +19574,19 @@ function registerEnrichCommand(program) {
19374
19574
  `
19375
19575
  );
19376
19576
  }
19577
+ const runtimeSourceCsvPath = options.inPlace ? sourceCsvPath : workingMergeSourceCsvPath === inputCsv ? inputCsv : (0, import_node_path12.join)(tempDir, `runtime-batch-${chunkIndex}.csv`);
19578
+ if (!options.inPlace && runtimeSourceCsvPath !== inputCsv) {
19579
+ await writeSlimBatchedRuntimeCsv({
19580
+ cleanSourceCsvPath: inputCsv,
19581
+ mergeSourceCsvPath: workingMergeSourceCsvPath,
19582
+ rows: chunkRows,
19583
+ compactAliases: runtimeCompactAliases,
19584
+ outputPath: runtimeSourceCsvPath
19585
+ });
19586
+ }
19377
19587
  const chunk = await runOne({
19378
- sourceCsvPath: workingSourceCsvPath,
19588
+ sourceCsvPath: runtimeSourceCsvPath,
19589
+ mergeSourceCsvPath: workingMergeSourceCsvPath,
19379
19590
  rows: chunkRows,
19380
19591
  json: true,
19381
19592
  passthroughStdout: false,
@@ -19385,7 +19596,10 @@ function registerEnrichCommand(program) {
19385
19596
  if (chunk.captured.result !== 0) {
19386
19597
  if (chunk.exportResult) {
19387
19598
  finalExportResult = chunk.exportResult;
19388
- totalEnrichedRows += chunk.exportResult.enrichedRows;
19599
+ totalEnrichedRows += countEnrichedRowsInSourceRange(
19600
+ chunk.exportResult,
19601
+ chunkRows
19602
+ );
19389
19603
  batchFailureRows.push(...chunk.exportResult.enrichedDataRows);
19390
19604
  }
19391
19605
  const failureReport3 = await maybeEmitEnrichFailureReport({
@@ -19446,9 +19660,12 @@ function registerEnrichCommand(program) {
19446
19660
  }
19447
19661
  if (chunk.exportResult) {
19448
19662
  finalExportResult = chunk.exportResult;
19449
- totalEnrichedRows += chunk.exportResult.enrichedRows;
19663
+ totalEnrichedRows += countEnrichedRowsInSourceRange(
19664
+ chunk.exportResult,
19665
+ chunkRows
19666
+ );
19450
19667
  batchFailureRows.push(...chunk.exportResult.enrichedDataRows);
19451
- workingSourceCsvPath = outputPath;
19668
+ workingMergeSourceCsvPath = outputPath;
19452
19669
  }
19453
19670
  }
19454
19671
  const outputRows = readCsvRows(outputPath);