deepline 0.3.279 → 0.3.281

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.
Files changed (35) hide show
  1. package/dist/bundling-sources/sdk/src/client.ts +7 -2
  2. package/dist/bundling-sources/sdk/src/csv-header-matching.ts +7 -0
  3. package/dist/bundling-sources/sdk/src/http.ts +16 -8
  4. package/dist/bundling-sources/sdk/src/index.ts +1 -1
  5. package/dist/bundling-sources/sdk/src/play.ts +1 -1
  6. package/dist/bundling-sources/sdk/src/release.ts +1 -1
  7. package/dist/bundling-sources/sdk/src/tool-calls.ts +2 -1
  8. package/dist/bundling-sources/sdk/src/types.ts +2 -0
  9. package/dist/bundling-sources/shared_libs/play-data-plane/runtime-sheet-storage-contract.ts +27 -0
  10. package/dist/bundling-sources/shared_libs/play-runtime/async-operation.ts +24 -5
  11. package/dist/bundling-sources/shared_libs/play-runtime/cell-provenance.ts +3 -1
  12. package/dist/bundling-sources/shared_libs/play-runtime/context.ts +14 -1
  13. package/dist/bundling-sources/shared_libs/play-runtime/runtime-api.ts +32 -9
  14. package/dist/bundling-sources/shared_libs/plays/authoring-contract.ts +1 -0
  15. package/dist/bundling-sources/shared_libs/plays/tool-result-types.ts +6 -5
  16. package/dist/cli/index.js +426 -53
  17. package/dist/cli/index.mjs +426 -53
  18. package/dist/{client-C0EhEIQO.d.mts → client-B0AjIkgb.d.mts} +6 -3
  19. package/dist/{client-HxPrGPbv.d.ts → client-BCXQ_Ftc.d.ts} +6 -3
  20. package/dist/{compiler-manifest-C1bKB9bY.d.mts → compiler-manifest-B1zo3igW.d.mts} +6 -5
  21. package/dist/{compiler-manifest-C1bKB9bY.d.ts → compiler-manifest-B1zo3igW.d.ts} +6 -5
  22. package/dist/index.d.mts +5 -5
  23. package/dist/index.d.ts +5 -5
  24. package/dist/index.js +198 -12
  25. package/dist/index.mjs +198 -12
  26. package/dist/install-integrity.json +5 -4
  27. package/dist/plays/bundle-play-file.d.mts +2 -2
  28. package/dist/plays/bundle-play-file.d.ts +2 -2
  29. package/dist/plays/run-request.d.mts +2 -2
  30. package/dist/plays/run-request.d.ts +2 -2
  31. package/dist/release.d.mts +1 -1
  32. package/dist/release.d.ts +1 -1
  33. package/dist/release.js +1 -1
  34. package/dist/release.mjs +1 -1
  35. package/package.json +1 -1
@@ -1960,6 +1960,9 @@ function playTriggerConfigPath(playName) {
1960
1960
  return `/api/v2/plays/${encodeURIComponent(playName)}/triggers`;
1961
1961
  }
1962
1962
 
1963
+ // src/csv-header-matching.ts
1964
+ var CSV_HEADER_MATCHING_NOTE = 'A header matches a column when it equals the column name or its default header, ignoring case, spaces and punctuation: LINKEDIN_URL, linkedin-url and "Linkedin Url" all match linkedin_url. A capital inside a word starts a new word, so "LinkedIn URL" reads as linked_in_url and does not match. Map any other header in the input: {"csv":"<path>","columns":{"<column>":"<your header>"}}.';
1965
+
1963
1966
  // src/pagination.ts
1964
1967
  async function* iterateCursorPages(fetchPage) {
1965
1968
  let cursor = null;
@@ -3507,7 +3510,7 @@ var SDK_RELEASE = {
3507
3510
  // getters keep their established compatibility behavior.
3508
3511
  // 0.3.1 deprecated the legacy `deepline enrich` command in favor of Plays.
3509
3512
  // 0.3.90 is the first deliberately versioned SDK release for API v3.
3510
- version: "0.3.279",
3513
+ version: "0.3.281",
3511
3514
  updateSummary: "Play grep now returns concise results with the matched fields and terms. Automatic CLI updates are enabled by default; use `deepline settings autoupdate off` to opt out, `deepline settings autoupdate on` to re-enable updates, or `deepline settings autoupdate pin <version>` to hold an exact release.",
3512
3515
  packageCapabilities: {
3513
3516
  updatePreferences: 1
@@ -4162,7 +4165,7 @@ function applyExplicitHeaders(headers, explicit) {
4162
4165
  for (const existing of Object.keys(headers)) {
4163
4166
  if (existing.toLowerCase() === name) delete headers[existing];
4164
4167
  }
4165
- headers[name] = value;
4168
+ headers[rawName.trim()] = value;
4166
4169
  }
4167
4170
  return headers;
4168
4171
  }
@@ -4250,7 +4253,7 @@ var HttpClient = class {
4250
4253
  }
4251
4254
  }
4252
4255
  authHeaders(extra) {
4253
- const headers = {
4256
+ const transportHeaders = {
4254
4257
  Authorization: `Bearer ${this.config.apiKey}`,
4255
4258
  "User-Agent": `deepline-ts-sdk/${SDK_VERSION}`,
4256
4259
  "X-Deepline-Client-Family": "sdk",
@@ -4259,10 +4262,9 @@ var HttpClient = class {
4259
4262
  "X-Deepline-CLI-Version": SDK_VERSION,
4260
4263
  "X-Deepline-SDK-Version": SDK_VERSION,
4261
4264
  "X-Deepline-API-Contract": SDK_API_CONTRACT,
4262
- "X-Deepline-Run-Result-Shape": "canonical",
4263
- ...extra,
4264
- ...deploymentProtectionHeaders()
4265
+ "X-Deepline-Run-Result-Shape": "canonical"
4265
4266
  };
4267
+ const headers = deploymentProtectionHeaders();
4266
4268
  const skillsVersion = this.readSkillsVersionHeader();
4267
4269
  if (skillsVersion) {
4268
4270
  headers["X-Deepline-Skills-Version"] = skillsVersion;
@@ -4308,7 +4310,13 @@ var HttpClient = class {
4308
4310
  if (coordinatorInternalToken?.trim() && (coordinatorUrl?.trim() || workerCallbackUrl?.trim() || runtimeTestFault?.trim() || absurdReleaseOverride?.trim() || preferredReceiptGatewayMachineId?.trim())) {
4309
4311
  headers[COORDINATOR_INTERNAL_TOKEN_HEADER] = coordinatorInternalToken.trim();
4310
4312
  }
4311
- return applyExplicitHeaders(headers, this.config.headers);
4313
+ return applyExplicitHeaders(
4314
+ applyExplicitHeaders(
4315
+ applyExplicitHeaders(transportHeaders, extra),
4316
+ headers
4317
+ ),
4318
+ this.config.headers
4319
+ );
4312
4320
  }
4313
4321
  /**
4314
4322
  * Send an HTTP request with automatic retries and error handling.
@@ -4332,7 +4340,7 @@ var HttpClient = class {
4332
4340
  let networkPhase = "before_request";
4333
4341
  const headers = this.authHeaders(options?.headers);
4334
4342
  if (options?.body !== void 0) {
4335
- headers["Content-Type"] = "application/json";
4343
+ applyExplicitHeaders(headers, { "Content-Type": "application/json" });
4336
4344
  }
4337
4345
  let lastError = null;
4338
4346
  const candidateUrls = options?.exactUrlOnly ? [url] : buildCandidateUrls(url);
@@ -4591,7 +4599,7 @@ var HttpClient = class {
4591
4599
  ...options?.headers
4592
4600
  });
4593
4601
  if (options?.body !== void 0) {
4594
- headers["Content-Type"] = "application/json";
4602
+ applyExplicitHeaders(headers, { "Content-Type": "application/json" });
4595
4603
  }
4596
4604
  let lastError = null;
4597
4605
  for (const candidateUrl of buildCandidateUrls(url)) {
@@ -5633,6 +5641,182 @@ var RUN_EVENT_SEARCH_FALLBACK_KIND_SQL_LITERAL = sqlStringLiteral(
5633
5641
  RUN_EVENT_SEARCH_FALLBACK_KIND
5634
5642
  );
5635
5643
 
5644
+ // ../play-data-plane/runtime-sheet-orm.ts
5645
+ var RUNTIME_SHEET_CELL_META_COLUMN = {
5646
+ name: "_cell_meta",
5647
+ dataType: "jsonb",
5648
+ nullable: "NO",
5649
+ defaultSql: "'{}'::jsonb"
5650
+ };
5651
+ var RUNTIME_SHEET_COLUMN_CONTRACTS = [
5652
+ {
5653
+ name: "_key",
5654
+ sqlType: "text",
5655
+ dataType: "text",
5656
+ nullable: "NO",
5657
+ defaultSql: null,
5658
+ repairable: false,
5659
+ requiresDefault: false
5660
+ },
5661
+ {
5662
+ name: "_status",
5663
+ sqlType: "text NOT NULL",
5664
+ dataType: "text",
5665
+ nullable: "NO",
5666
+ defaultSql: null,
5667
+ repairable: false,
5668
+ requiresDefault: false
5669
+ },
5670
+ {
5671
+ name: "_run_id",
5672
+ sqlType: "text",
5673
+ dataType: "text",
5674
+ nullable: "YES",
5675
+ defaultSql: null,
5676
+ repairable: true,
5677
+ requiresDefault: false
5678
+ },
5679
+ {
5680
+ name: "_error",
5681
+ sqlType: "text",
5682
+ dataType: "text",
5683
+ nullable: "YES",
5684
+ defaultSql: null,
5685
+ repairable: true,
5686
+ requiresDefault: false
5687
+ },
5688
+ {
5689
+ name: "_stage",
5690
+ sqlType: "text",
5691
+ dataType: "text",
5692
+ nullable: "YES",
5693
+ defaultSql: null,
5694
+ repairable: true,
5695
+ requiresDefault: false
5696
+ },
5697
+ {
5698
+ name: "_provider",
5699
+ sqlType: "text",
5700
+ dataType: "text",
5701
+ nullable: "YES",
5702
+ defaultSql: null,
5703
+ repairable: true,
5704
+ requiresDefault: false
5705
+ },
5706
+ {
5707
+ name: "_input_index",
5708
+ sqlType: "bigint",
5709
+ dataType: "bigint",
5710
+ nullable: "YES",
5711
+ defaultSql: null,
5712
+ repairable: true,
5713
+ requiresDefault: false
5714
+ },
5715
+ {
5716
+ name: "_attempt_id",
5717
+ sqlType: "text",
5718
+ dataType: "text",
5719
+ nullable: "YES",
5720
+ defaultSql: null,
5721
+ repairable: true,
5722
+ requiresDefault: false
5723
+ },
5724
+ {
5725
+ name: "_attempt_owner_run_id",
5726
+ sqlType: "text",
5727
+ dataType: "text",
5728
+ nullable: "YES",
5729
+ defaultSql: null,
5730
+ repairable: true,
5731
+ requiresDefault: false
5732
+ },
5733
+ {
5734
+ name: "_attempt_expires_at",
5735
+ sqlType: "timestamptz",
5736
+ dataType: "timestamp with time zone",
5737
+ nullable: "YES",
5738
+ defaultSql: null,
5739
+ repairable: true,
5740
+ requiresDefault: false
5741
+ },
5742
+ {
5743
+ name: "_attempt_seq",
5744
+ sqlType: "integer",
5745
+ dataType: "integer",
5746
+ nullable: "YES",
5747
+ defaultSql: null,
5748
+ repairable: true,
5749
+ requiresDefault: false
5750
+ },
5751
+ {
5752
+ name: "_write_version",
5753
+ sqlType: "bigint NOT NULL DEFAULT 0",
5754
+ dataType: "bigint",
5755
+ nullable: "NO",
5756
+ defaultSql: "0",
5757
+ repairable: true,
5758
+ requiresDefault: true
5759
+ },
5760
+ {
5761
+ name: "_writer_run_id",
5762
+ sqlType: "text",
5763
+ dataType: "text",
5764
+ nullable: "YES",
5765
+ defaultSql: null,
5766
+ repairable: true,
5767
+ requiresDefault: false
5768
+ },
5769
+ {
5770
+ name: "_created_at",
5771
+ sqlType: "timestamptz NOT NULL DEFAULT now()",
5772
+ dataType: "timestamp with time zone",
5773
+ nullable: "NO",
5774
+ defaultSql: "now()",
5775
+ repairable: true,
5776
+ requiresDefault: true
5777
+ },
5778
+ {
5779
+ name: "_updated_at",
5780
+ sqlType: "timestamptz NOT NULL DEFAULT now()",
5781
+ dataType: "timestamp with time zone",
5782
+ nullable: "NO",
5783
+ defaultSql: "now()",
5784
+ repairable: true,
5785
+ requiresDefault: true
5786
+ },
5787
+ {
5788
+ name: "_version",
5789
+ sqlType: "bigint NOT NULL",
5790
+ dataType: "bigint",
5791
+ nullable: "NO",
5792
+ defaultSql: null,
5793
+ defaultKind: "version_sequence",
5794
+ repairable: true,
5795
+ requiresDefault: true
5796
+ },
5797
+ {
5798
+ ...RUNTIME_SHEET_CELL_META_COLUMN,
5799
+ sqlType: `jsonb NOT NULL DEFAULT ${RUNTIME_SHEET_CELL_META_COLUMN.defaultSql}`,
5800
+ repairable: true,
5801
+ requiresDefault: true
5802
+ }
5803
+ ];
5804
+ var RUNTIME_SHEET_ATTEMPT_COLUMNS = RUNTIME_SHEET_COLUMN_CONTRACTS.filter(
5805
+ (column) => column.name.startsWith("_attempt_")
5806
+ ).map((column) => column.name);
5807
+ var RUNTIME_SHEET_WRITE_VERSION_COLUMNS = RUNTIME_SHEET_COLUMN_CONTRACTS.filter(
5808
+ (column) => column.name === "_write_version" || column.name === "_writer_run_id"
5809
+ ).map((column) => column.name);
5810
+ var RUNTIME_SHEET_TIMESTAMP_COLUMNS = RUNTIME_SHEET_COLUMN_CONTRACTS.filter(
5811
+ (column) => column.name === "_created_at" || column.name === "_updated_at"
5812
+ ).map((column) => column.name);
5813
+ var RUNTIME_SHEET_SYSTEM_COLUMNS = new Set(
5814
+ RUNTIME_SHEET_COLUMN_CONTRACTS.map((column) => column.name)
5815
+ );
5816
+ var RUNTIME_SHEET_REPAIRABLE_COLUMNS = RUNTIME_SHEET_COLUMN_CONTRACTS.filter(
5817
+ (column) => column.repairable
5818
+ );
5819
+
5636
5820
  // ../play-runtime/run-ledger.ts
5637
5821
  var TERMINAL_STATUS_BY_EVENT_TYPE = {
5638
5822
  [RUN_EVENT_KIND.runCompleted]: "completed",
@@ -7361,7 +7545,9 @@ var DeeplineClient = class _DeeplineClient {
7361
7545
  inputSchema: options?.compact ? this.compactSchema(play.inputSchema) : play.inputSchema ?? null,
7362
7546
  outputSchema: options?.compact ? this.compactSchema(play.outputSchema) : play.outputSchema ?? null,
7363
7547
  staticPipeline: isRecord4(play.staticPipeline) ? play.staticPipeline : isRecord4(play.currentRevision?.staticPipeline) ? play.currentRevision.staticPipeline : isRecord4(play.liveRevision?.staticPipeline) ? play.liveRevision.staticPipeline : null,
7364
- ...csvInput ? { csvInput } : {},
7548
+ ...csvInput ? {
7549
+ csvInput: { ...csvInput, headerMatching: CSV_HEADER_MATCHING_NOTE }
7550
+ } : {},
7365
7551
  ...rowOutputSchema ? { rowOutputSchema } : {},
7366
7552
  runCommand: runCommand2,
7367
7553
  examples: [runCommand2],
@@ -7574,7 +7760,7 @@ var DeeplineClient = class _DeeplineClient {
7574
7760
  /**
7575
7761
  * Execute a tool and return the standard execution envelope.
7576
7762
  *
7577
- * The `toolResponse.raw` field contains the raw tool response.
7763
+ * The `toolResponse.rawV2` field contains the complete parsed and scrubbed tool response.
7578
7764
  * `toolResponse.meta` contains tool/provider metadata.
7579
7765
  * Top-level fields such as `status`, `job_id`, and `billing` describe the
7580
7766
  * Deepline execution envelope.
@@ -12543,15 +12729,42 @@ async function handleBalance(options) {
12543
12729
  const lines = [`Balance: ${payload.balance ?? "(unknown)"} credits`];
12544
12730
  const temporaryHolds = payload.temporary_hold_credits;
12545
12731
  if (typeof temporaryHolds === "number" && temporaryHolds > 0) {
12546
- lines.push(
12547
- `Temporarily reserved: ${temporaryHolds} credits \u2014 not charged; unused credits are released after final usage is calculated.`
12548
- );
12732
+ lines.push(`Open reservation exposure: ${temporaryHolds} credits.`);
12549
12733
  } else if (temporaryHolds === null) {
12550
12734
  lines.push("Temporary reservation status is temporarily unavailable.");
12551
12735
  }
12552
12736
  if (payload.temporary_hold_credits_truncated === true) {
12553
12737
  lines.push("Temporary reservation total may be incomplete.");
12554
12738
  }
12739
+ if (typeof payload.estimated_hold_credits === "number") {
12740
+ lines.push(
12741
+ `Estimated holds: ${payload.estimated_hold_credits} credits \u2014 final usage is not recorded yet.`
12742
+ );
12743
+ }
12744
+ if (typeof payload.incurred_unsettled_credits === "number") {
12745
+ lines.push(
12746
+ `Incurred, awaiting settlement: ${payload.incurred_unsettled_credits} credits.`
12747
+ );
12748
+ }
12749
+ if (typeof payload.pending_wallet_debit_credits === "number") {
12750
+ lines.push(
12751
+ `Pending wallet debit: ${payload.pending_wallet_debit_credits} credits \u2014 excludes amounts already debited for funded holds.`
12752
+ );
12753
+ }
12754
+ if (typeof payload.pending_wallet_refund_credits === "number" && payload.pending_wallet_refund_credits > 0) {
12755
+ lines.push(
12756
+ `Pending wallet refund: ${payload.pending_wallet_refund_credits} credits.`
12757
+ );
12758
+ }
12759
+ if (payload.exposure_status === "partial") {
12760
+ lines.push(
12761
+ "Exposure amounts are lower bounds: some reservations are unpriced or the scan is incomplete."
12762
+ );
12763
+ } else if (payload.exposure_status !== "complete") {
12764
+ lines.push(
12765
+ "The estimated and incurred usage breakdown is temporarily unavailable."
12766
+ );
12767
+ }
12555
12768
  if (status === "no_billing") {
12556
12769
  lines.push(
12557
12770
  "Billing: No billing account or payment method set up for this workspace."
@@ -25513,7 +25726,7 @@ async function traceCliSpan(phase, fields2, run) {
25513
25726
  }
25514
25727
 
25515
25728
  // src/cli/play-check-hints.ts
25516
- var EXTRACTED_GETTER_ERROR_HINT = "Deepline hint: extractedValues/extractedLists .get() only works for declared Deepline getters listed by `deepline tools describe <tool> --json`. Use `toolExecutionResult.toolResponse.raw` for provider/tool-specific scalar fields, and `toolExecutionResult.extractedLists.<name>.get()` for declared row/list outputs.";
25729
+ var EXTRACTED_GETTER_ERROR_HINT = "Deepline hint: extractedValues/extractedLists .get() only works for declared Deepline getters listed by `deepline tools describe <tool> --json`. Use `toolExecutionResult.toolResponse.rawV2` for provider/tool-specific scalar fields after inspecting the observed response envelope, and `toolExecutionResult.extractedLists.<name>.get()` for declared row/list outputs.";
25517
25730
  var DATASET_API_HINT = "Deepline hint: PlayDataset is lazy, durable, and async-only. Use `.count()`, `.first()`, `.at(index)`, `.peek(n)`, `.materialize(limit)`, or async iteration; do not use `.length`, numeric indexing, spread, synchronous iteration, `.rows`, or `.toArray()`.";
25518
25731
  var ROW_PROPERTY_HINT = "Deepline hint: this row type only contains fields produced by the CSV/schema and previous map steps. Check source column casing and the exact output field names from earlier steps before scaling.";
25519
25732
  var TOOLS_EXECUTE_SIGNATURE_HINT = "Deepline hint: ctx.tools.execute requires a request object: `ctx.tools.execute({ id, tool, input, description })`. The stable `id` is required for logs, metadata, and result-cache identity; terminal cache reuse is based on play, tool, semantic input, auth scope, provider action version, and cache policy.";
@@ -32004,6 +32217,7 @@ async function fetchBackingDatasetRows(input2) {
32004
32217
  return null;
32005
32218
  }
32006
32219
  const sheetRows = [];
32220
+ const seenEnvelopeKeys = /* @__PURE__ */ new Set();
32007
32221
  let offset = 0;
32008
32222
  let settledTotal = null;
32009
32223
  while (true) {
@@ -32015,6 +32229,27 @@ async function fetchBackingDatasetRows(input2) {
32015
32229
  offset,
32016
32230
  rowMode: "all"
32017
32231
  });
32232
+ for (const row of page.rows) {
32233
+ const key = readRecord(getRecordField(row, "data")) ? getStringField(row, "key") : null;
32234
+ if (key === null) continue;
32235
+ if (seenEnvelopeKeys.has(key)) {
32236
+ const activeRun = !TERMINAL_PLAY_STATUSES.has(input2.status.status);
32237
+ const waitCommand = `${input2.retryCommand} --wait`;
32238
+ throw new DeeplineError(
32239
+ "The backing dataset returned a Runtime Sheet row more than once while paging; the export is not ready to write. " + (activeRun ? `Wait for this same run: ${waitCommand}. Do not rerun the Play to retrieve results.` : `Retry with: ${input2.retryCommand}`),
32240
+ void 0,
32241
+ "RUN_EXPORT_NOT_READY",
32242
+ {
32243
+ runId: input2.status.runId,
32244
+ reason: "unstable_pagination",
32245
+ tableNamespace,
32246
+ retry_command: input2.retryCommand,
32247
+ ...activeRun ? { wait_command: waitCommand, do_not_rerun: true } : {}
32248
+ }
32249
+ );
32250
+ }
32251
+ seenEnvelopeKeys.add(key);
32252
+ }
32018
32253
  sheetRows.push(...page.rows);
32019
32254
  const summaryTotal = page.summary?.stats?.total;
32020
32255
  if (typeof summaryTotal === "number" && Number.isFinite(summaryTotal)) {
@@ -32030,15 +32265,23 @@ async function fetchBackingDatasetRows(input2) {
32030
32265
  (row) => Boolean(row) && typeof row === "object" && !Array.isArray(row)
32031
32266
  )
32032
32267
  );
32033
- const rows = sheetRows.map((row) => {
32034
- const data = exportableSheetRow(row);
32035
- return data && withError ? {
32036
- ...data,
32037
- [TABLE_EXPORT_ERROR_COLUMN]: tableExportErrorCell(
32038
- row
32039
- )
32040
- } : data;
32041
- }).filter((row) => Boolean(row));
32268
+ const exportedRowOutcomes = { succeeded: 0, failed: 0, unconfirmed: 0 };
32269
+ const rows = sheetRows.flatMap((row) => {
32270
+ const exported = exportableSheetRow(row);
32271
+ if (!exported) return [];
32272
+ const status = readRecord(getRecordField(row, "data")) ? getStringField(row, "status") : null;
32273
+ if (status === "completed") exportedRowOutcomes.succeeded += 1;
32274
+ else if (status === "failed") exportedRowOutcomes.failed += 1;
32275
+ else exportedRowOutcomes.unconfirmed += 1;
32276
+ return [
32277
+ withError ? {
32278
+ ...exported,
32279
+ [TABLE_EXPORT_ERROR_COLUMN]: tableExportErrorCell(
32280
+ row
32281
+ )
32282
+ } : exported
32283
+ ];
32284
+ });
32042
32285
  const hasCompleteSettledPrefix = acceptsSettledRowsAsCompleteExport(input2.status) && settledTotal !== null && // A zero-row run-scoped read is not a settled export when the returned
32043
32286
  // Dataset Handle advertised rows. That shape is the replay/reuse case:
32044
32287
  // the rows belong to another writer (or the projection has not caught up)
@@ -32053,7 +32296,8 @@ async function fetchBackingDatasetRows(input2) {
32053
32296
  source: `${input2.rowsInfo.source ?? "result.rows"} -> /api/v2/plays/${playName}/sheet?tableNamespace=${tableNamespace}`
32054
32297
  };
32055
32298
  }
32056
- if (rows.length < input2.rowsInfo.totalRows && !hasCompleteSettledPrefix) {
32299
+ const hasActiveSnapshot = !TERMINAL_PLAY_STATUSES.has(input2.status.status) && rows.length > 0 && exportedRowOutcomes.unconfirmed === 0;
32300
+ if (rows.length < input2.rowsInfo.totalRows && !hasCompleteSettledPrefix && !hasActiveSnapshot) {
32057
32301
  return null;
32058
32302
  }
32059
32303
  const columns = mergeExportColumns(
@@ -32065,7 +32309,10 @@ async function fetchBackingDatasetRows(input2) {
32065
32309
  rows,
32066
32310
  columns,
32067
32311
  totalRows: rows.length,
32312
+ // All pages of the selected snapshot were fetched. The CLI receipt
32313
+ // independently marks an active run's export as partial.
32068
32314
  complete: true,
32315
+ exportedRowOutcomes,
32069
32316
  currentTable: void 0,
32070
32317
  source: `${input2.rowsInfo.source ?? "result.rows"} -> /api/v2/plays/${playName}/sheet?tableNamespace=${tableNamespace}`
32071
32318
  };
@@ -32106,10 +32353,30 @@ function assertDatasetHasExportableRows(input2) {
32106
32353
  const inspectCommand = `deepline runs get ${input2.status.runId} --full --json`;
32107
32354
  const retryCommand = runExportRetryCommand(
32108
32355
  input2.status.runId,
32109
- "output.csv",
32110
- datasetLabel
32356
+ input2.outPath ?? "output.csv",
32357
+ datasetLabel,
32358
+ input2.format ? { format: input2.format } : void 0
32111
32359
  );
32112
32360
  const currentTableQueryCommand2 = input2.rowsInfo.currentTableQueryCommand;
32361
+ if (!TERMINAL_PLAY_STATUSES.has(input2.status.status)) {
32362
+ const waitCommand = `${retryCommand} --wait`;
32363
+ throw new DeeplineError(
32364
+ `Run ${input2.status.runId} is ${runStatus}; this dataset has no accepted rows to export yet. Wait for this same run: ${waitCommand}. Do not start another run to retrieve results.`,
32365
+ void 0,
32366
+ "RUN_EXPORT_EMPTY",
32367
+ {
32368
+ runId: input2.status.runId,
32369
+ dataset: datasetLabel,
32370
+ runStatus,
32371
+ guidance: {
32372
+ wait_command: waitCommand,
32373
+ inspect_command: inspectCommand,
32374
+ do_not_rerun: true,
32375
+ reason: "The run is still active and has no accepted rows in this dataset."
32376
+ }
32377
+ }
32378
+ );
32379
+ }
32113
32380
  const explanation = terminalRunWithMissingAdvertisedRows ? ` The terminal result advertised ${advertisedRows} row(s), but none are currently attributed to this run's durable sheet. Those rows may have been reused from an earlier run or the projection may still be lagging; export refuses to guess another run's rows. Retry the same export after projection catches up (do not rerun the Play): ${retryCommand}. If it remains empty, inspect the full package with ${inspectCommand}` + (currentTableQueryCommand2 ? `, then inspect the current table's _run_id/_writer_run_id with ${currentTableQueryCommand2} and export the run that owns those rows` : " and export the run that owns the durable dataset") + "; this command will not use a database-wide table query that could mix runs." : ` The run status is '${runStatus || "unknown"}', so it likely failed before persisting rows to this dataset. That means provider calls may have been billed without a durable row; inspect ${inspectCommand}, fix the failure cause, then rerun the Play so completed receipts can be reused.`;
32114
32381
  throw new DeeplineError(
32115
32382
  `Run ${input2.status.runId} has zero rows to export from dataset '${datasetLabel}'.` + explanation + (available.length > 0 ? ` Available datasets: ${available.join(", ")}.` : " No datasets were materialized for this run."),
@@ -32246,16 +32513,23 @@ ${commands.join("\n")}`,
32246
32513
  }
32247
32514
  const attempts = Math.max(1, Math.trunc(options.attempts ?? 1));
32248
32515
  const retryDelayMs = Math.max(0, Math.trunc(options.retryDelayMs ?? 0));
32516
+ const retryCommand = runExportRetryCommand(
32517
+ status.runId,
32518
+ outPath,
32519
+ options.datasetPath ?? rowsInfo.source,
32520
+ options
32521
+ );
32249
32522
  for (let attempt = 1; attempt <= attempts; attempt += 1) {
32250
32523
  let fetchedRowsInfo = null;
32251
32524
  try {
32252
32525
  fetchedRowsInfo = await fetchBackingDatasetRows({
32253
32526
  client: client2,
32254
32527
  status,
32255
- rowsInfo
32528
+ rowsInfo,
32529
+ retryCommand
32256
32530
  });
32257
32531
  } catch (error) {
32258
- if (error instanceof DeeplineError && error.code === "RUN_EXPORT_SCOPE_MISMATCH") {
32532
+ if (error instanceof DeeplineError && (error.code === "RUN_EXPORT_SCOPE_MISMATCH" || error.code === "RUN_EXPORT_NOT_READY")) {
32259
32533
  throw error;
32260
32534
  }
32261
32535
  if (!canExportPreview) {
@@ -32267,7 +32541,9 @@ ${commands.join("\n")}`,
32267
32541
  rowsInfo: fetchedRowsInfo,
32268
32542
  status,
32269
32543
  availableRows,
32270
- datasetPath: options.datasetPath
32544
+ datasetPath: options.datasetPath,
32545
+ outPath,
32546
+ format: options.format
32271
32547
  });
32272
32548
  return writeExport(guarded2);
32273
32549
  }
@@ -32276,7 +32552,9 @@ ${commands.join("\n")}`,
32276
32552
  rowsInfo,
32277
32553
  status,
32278
32554
  availableRows,
32279
- datasetPath: options.datasetPath
32555
+ datasetPath: options.datasetPath,
32556
+ outPath,
32557
+ format: options.format
32280
32558
  });
32281
32559
  return writeExport(guarded2);
32282
32560
  }
@@ -32285,15 +32563,11 @@ ${commands.join("\n")}`,
32285
32563
  }
32286
32564
  }
32287
32565
  if (!canExportPreview) {
32288
- const retryCommand = runExportRetryCommand(
32289
- status.runId,
32290
- outPath,
32291
- options.datasetPath ?? rowsInfo.source,
32292
- options
32293
- );
32294
32566
  const previewReason = rowsInfo.currentTable ? "Legacy shared-table metadata does not prove this preview belongs to the run" : `Run output only includes ${rowsInfo.rows.length} preview row(s) of ${rowsInfo.totalRows}`;
32567
+ const activeRun = !TERMINAL_PLAY_STATUSES.has(status.status);
32568
+ const waitCommand = `${retryCommand} --wait`;
32295
32569
  throw new DeeplineError(
32296
- `${previewReason}; the backing dataset was not ready to export yet. Retry with: ${retryCommand}`,
32570
+ `${previewReason}; the backing dataset was not ready to export yet. ` + (activeRun ? `The run is ${status.status}. Wait for this same run: ${waitCommand}. Do not rerun the Play to retrieve results.` : `Retry with: ${retryCommand}`),
32297
32571
  void 0,
32298
32572
  "RUN_EXPORT_NOT_READY",
32299
32573
  {
@@ -32302,7 +32576,8 @@ ${commands.join("\n")}`,
32302
32576
  totalRows: rowsInfo.totalRows,
32303
32577
  tableNamespace: rowsInfo.tableNamespace ?? null,
32304
32578
  dataset: options.datasetPath ?? rowsInfo.source,
32305
- retry_command: retryCommand
32579
+ retry_command: retryCommand,
32580
+ ...activeRun ? { wait_command: waitCommand, do_not_rerun: true } : {}
32306
32581
  }
32307
32582
  );
32308
32583
  }
@@ -32310,7 +32585,9 @@ ${commands.join("\n")}`,
32310
32585
  rowsInfo,
32311
32586
  status,
32312
32587
  availableRows,
32313
- datasetPath: options.datasetPath
32588
+ datasetPath: options.datasetPath,
32589
+ outPath,
32590
+ format: options.format
32314
32591
  });
32315
32592
  return writeExport(guarded);
32316
32593
  }
@@ -33070,7 +33347,7 @@ function checkHintExpression(value) {
33070
33347
  return stringValue3(value).replace(/^toolExecutionResult\./, "result.");
33071
33348
  }
33072
33349
  function checkHintRawPath(value) {
33073
- return value?.replace(/^toolResponse\./, "result.toolResponse.");
33350
+ return value?.startsWith("toolResponse.rawV2") ? value.replace(/^toolResponse\./, "result.toolResponse.") : void 0;
33074
33351
  }
33075
33352
  function collectStaticPipelineToolIds(staticPipeline) {
33076
33353
  const seen = /* @__PURE__ */ new Set();
@@ -33115,7 +33392,7 @@ function toolGetterHintFromMetadata(toolId, tool) {
33115
33392
  toolId,
33116
33393
  lists,
33117
33394
  values,
33118
- raw: checkHintExpression(toolResponse.raw) || "result.toolResponse.raw"
33395
+ raw: checkHintExpression(toolResponse.rawV2) || "result.toolResponse.rawV2"
33119
33396
  };
33120
33397
  }
33121
33398
  async function buildToolGetterHints(client2, staticPipeline) {
@@ -33130,7 +33407,7 @@ async function buildToolGetterHints(client2, staticPipeline) {
33130
33407
  toolId,
33131
33408
  lists: [],
33132
33409
  values: [],
33133
- raw: "result.toolResponse.raw",
33410
+ raw: "result.toolResponse.rawV2",
33134
33411
  unavailable: error instanceof Error ? error.message : String(error)
33135
33412
  };
33136
33413
  }
@@ -35118,7 +35395,7 @@ async function handleRunStopAll(args) {
35118
35395
  async function handleRunExport(args) {
35119
35396
  const selection = parseJsonFields(args, "export");
35120
35397
  args = selection.args;
35121
- const usage2 = "Usage: deepline runs export <run-id> [--dataset result.rows] --out <path> [--format csv|json] [--metadata-out export.json] [--json]";
35398
+ const usage2 = "Usage: deepline runs export <run-id> [--dataset result.rows] --out <path> [--format csv|json] [--wait] [--timeout-ms 300000] [--metadata-out export.json] [--json]";
35122
35399
  let runId;
35123
35400
  try {
35124
35401
  runId = parseRunIdPositional(args, usage2);
@@ -35130,6 +35407,8 @@ async function handleRunExport(args) {
35130
35407
  let datasetPath = null;
35131
35408
  let metadataOutPath = null;
35132
35409
  let format = "csv";
35410
+ const wait = args.includes("--wait");
35411
+ let waitTimeoutMs = 3e5;
35133
35412
  for (let index = 0; index < args.length; index += 1) {
35134
35413
  const arg = args[index];
35135
35414
  if (arg === "--out" && args[index + 1]) {
@@ -35144,6 +35423,16 @@ async function handleRunExport(args) {
35144
35423
  metadataOutPath = resolve13(args[++index]);
35145
35424
  }
35146
35425
  if (arg === "--format") format = args[++index] ?? "";
35426
+ if (arg === "--timeout-ms") {
35427
+ waitTimeoutMs = parsePositiveInteger3(args[++index] ?? "", arg);
35428
+ if (!wait) {
35429
+ throw new DeeplineError(
35430
+ "--timeout-ms requires --wait.",
35431
+ void 0,
35432
+ "INVALID_ARGUMENT"
35433
+ );
35434
+ }
35435
+ }
35147
35436
  }
35148
35437
  if (!outPath) {
35149
35438
  console.error(usage2);
@@ -35164,7 +35453,33 @@ async function handleRunExport(args) {
35164
35453
  );
35165
35454
  }
35166
35455
  const client2 = new DeeplineClient();
35167
- const status = await client2.getPlayStatus(runId, { full: true });
35456
+ let status = await client2.getPlayStatus(runId, { full: true });
35457
+ if (wait && !TERMINAL_PLAY_STATUSES.has(status.status)) {
35458
+ const progress = createCliProgress(!argsWantJson(args));
35459
+ try {
35460
+ await waitForPlayCompletionByWatch({
35461
+ client: client2,
35462
+ playName: extractRunPlayName(status) ?? runId,
35463
+ workflowId: runId,
35464
+ jsonOutput: argsWantJson(args),
35465
+ emitLogs: false,
35466
+ waitTimeoutMs,
35467
+ startedAt: Date.now(),
35468
+ state: {
35469
+ emittedRunnerStarted: false,
35470
+ lastProgressSignature: null,
35471
+ lastProgressHeartbeatAt: 0,
35472
+ lastStatusHeartbeatAt: 0
35473
+ },
35474
+ progress
35475
+ });
35476
+ status = await client2.getPlayStatus(runId, { full: true });
35477
+ progress.complete();
35478
+ } catch (error) {
35479
+ progress.fail();
35480
+ throw error;
35481
+ }
35482
+ }
35168
35483
  const exportResult = await exportPlayStatusRows(client2, status, outPath, {
35169
35484
  datasetPath,
35170
35485
  format
@@ -35188,8 +35503,16 @@ async function handleRunExport(args) {
35188
35503
  { format }
35189
35504
  );
35190
35505
  const fileLocation = format === "json" ? { json_path: exportResult?.path ?? null } : { csv_path: exportResult?.path ?? null };
35506
+ const exportedRowOutcomes = exportResult?.rowsInfo.exportedRowOutcomes;
35507
+ const rowFailures = exportedRowOutcomes && exportedRowOutcomes.failed > 0 ? {
35508
+ count: exportedRowOutcomes.failed,
35509
+ message: "Failed rows can retain values from stages that completed earlier; those values do not prove the row succeeded.",
35510
+ inspectCommand: `deepline runs get ${status.runId} --json`
35511
+ } : null;
35191
35512
  const payload = {
35192
35513
  runId: status.runId,
35514
+ runStatus: status.status,
35515
+ isPartial: !TERMINAL_PLAY_STATUSES.has(status.status),
35193
35516
  datasets: identity ? [identity] : resolved ? [
35194
35517
  {
35195
35518
  ...resolved.datasetId ? { datasetId: resolved.datasetId } : {},
@@ -35201,18 +35524,30 @@ async function handleRunExport(args) {
35201
35524
  format,
35202
35525
  source,
35203
35526
  rowCount: exportResult?.rowsInfo.totalRows ?? null,
35527
+ ...exportedRowOutcomes ? { rowOutcomes: exportedRowOutcomes } : {},
35528
+ ...rowFailures ? { rowFailures } : {},
35204
35529
  columns: underscoreKeysLast(exportResult?.rowsInfo.columns ?? []),
35205
35530
  ...currentTableNotice ? { notice: currentTableNotice } : {},
35206
- ...metadataOutPath ? { metadata_path: metadataOutPath } : {}
35531
+ ...metadataOutPath ? { metadata_path: metadataOutPath } : {},
35532
+ ...!TERMINAL_PLAY_STATUSES.has(status.status) ? { completionCommand: `${exportCommand} --wait` } : {}
35207
35533
  };
35208
35534
  const lines = withRunNavigationLines(
35209
35535
  [
35210
35536
  `Exported ${status.runId} to ${exportResult?.path ?? outPath}`,
35537
+ ...!TERMINAL_PLAY_STATUSES.has(status.status) ? [
35538
+ `Partial export: run is ${status.status}; more rows may be saved.`,
35539
+ `Export after completion: ${exportCommand} --wait`
35540
+ ] : status.status === "failed" || status.status === "cancelled" ? [
35541
+ `Saved rows from a ${status.status} run. Inspect: deepline runs get ${status.runId} --json`
35542
+ ] : [],
35211
35543
  ...currentTableNotice ? [
35212
35544
  "Current shared dataset: this export may include writes from another run.",
35213
35545
  `This run's full returned output: ${currentTableNotice.full_run_output_command}`
35214
35546
  ] : [],
35215
- ...source ? [`source=${source}`] : []
35547
+ ...source ? [`source=${source}`] : [],
35548
+ ...rowFailures ? [
35549
+ `${rowFailures.count} failed row(s) included. Earlier saved values do not prove success. Inspect: ${rowFailures.inspectCommand}`
35550
+ ] : []
35216
35551
  ],
35217
35552
  status,
35218
35553
  payload.actions
@@ -35598,6 +35933,21 @@ function parsePlaySearchOptions(args) {
35598
35933
  function playSearchDisclaimer(scope) {
35599
35934
  return scope === "all" ? "Prebuilt-first search: Deepline-managed prebuilts are trusted, robust plays with maintained contracts, so they are listed before plays you created. Use created-play results only when you are specifically looking for one." : "Prebuilt-first search: Deepline-managed prebuilts are trusted, robust plays with maintained contracts. Plays you created are omitted by default; add --all only when you are specifically looking for one.";
35600
35935
  }
35936
+ function csvColumnLines(csvInput) {
35937
+ const rowSchema = isRecord7(csvInput.rowInputSchema) ? csvInput.rowInputSchema : {};
35938
+ const columns = isRecord7(rowSchema.properties) ? Object.keys(rowSchema.properties) : [];
35939
+ const required = new Set(
35940
+ Array.isArray(rowSchema.required) ? rowSchema.required.map(String) : []
35941
+ );
35942
+ const defaults = isRecord7(csvInput.defaultColumns) ? csvInput.defaultColumns : {};
35943
+ return [
35944
+ ...columns.map((column) => {
35945
+ const headers = [defaults[column]].flat().filter((header) => header && header !== column);
35946
+ return `${column}${required.has(column) ? " (required)" : ""}${headers.length > 0 ? `, default header: ${headers.join(" or ")}` : ""}`;
35947
+ }),
35948
+ CSV_HEADER_MATCHING_NOTE
35949
+ ];
35950
+ }
35601
35951
  function printPlayDescription(play) {
35602
35952
  const reference = formatPlayListReference(play);
35603
35953
  const labels = [
@@ -35618,6 +35968,12 @@ function printPlayDescription(play) {
35618
35968
  if (play.pinned) {
35619
35969
  console.log(" Pinned: yes");
35620
35970
  }
35971
+ if (play.csvInput) {
35972
+ console.log(" CSV columns:");
35973
+ for (const line of csvColumnLines(play.csvInput)) {
35974
+ console.log(` ${line}`);
35975
+ }
35976
+ }
35621
35977
  if (play.toolCategories?.length) {
35622
35978
  console.log(` Tool categories: ${play.toolCategories.join(", ")}`);
35623
35979
  }
@@ -37339,6 +37695,10 @@ Notes:
37339
37695
  --json controls stdout metadata, not the file format.
37340
37696
  --metadata-out writes the same export metadata object returned by --json,
37341
37697
  including the source dataset path and row/column metadata.
37698
+ An active run exports only the rows accepted so far; the receipt labels it
37699
+ partial. --wait observes the same run until it completes, fails, or is cancelled
37700
+ before exporting its saved rows. --timeout-ms bounds that wait (default 300000);
37701
+ a wait timeout leaves the run and destination file untouched.
37342
37702
 
37343
37703
  Examples:
37344
37704
  deepline runs export play/my-play/run/20260501t000000-000 --out output.csv
@@ -37346,11 +37706,15 @@ Examples:
37346
37706
  deepline runs export play/my-play/run/20260501t000000-000 --out output.csv --metadata-out output.meta.json
37347
37707
  deepline runs export play/my-play/run/20260501t000000-000 --out output.csv --json
37348
37708
  deepline runs export play/my-play/run/20260501t000000-000 --format json --out rows.json
37709
+ deepline runs export play/my-play/run/20260501t000000-000 --out rows.csv --wait --timeout-ms 600000
37349
37710
  `
37350
37711
  ).requiredOption("--out <path>", "Output file path").option("--format <format>", "File format: csv or json", "csv").option(
37351
37712
  "--dataset <path>",
37352
37713
  "Returned dataset handle path, such as result.rows"
37353
37714
  ).option("--metadata-out <path>", "Write export metadata JSON to a file").option(
37715
+ "--wait",
37716
+ "Wait for this run to reach a terminal status before export"
37717
+ ).option("--timeout-ms <ms>", "Maximum wait with --wait (default: 300000)").option(
37354
37718
  "--json [fields]",
37355
37719
  "JSON receipt; optionally select fields (dataset,datasets,actions). Does not filter exported rows"
37356
37720
  ).action(async (runId, options) => {
@@ -37362,6 +37726,8 @@ Examples:
37362
37726
  "--format",
37363
37727
  options.format,
37364
37728
  ...options.metadataOut ? ["--metadata-out", options.metadataOut] : [],
37729
+ ...options.wait ? ["--wait"] : [],
37730
+ ...options.timeoutMs ? ["--timeout-ms", options.timeoutMs] : [],
37365
37731
  ...jsonFieldArgs(options.json)
37366
37732
  ]);
37367
37733
  });
@@ -56180,6 +56546,9 @@ function printCompactToolContract(tool, requestedToolId) {
56180
56546
  }
56181
56547
  }
56182
56548
  console.log("");
56549
+ console.log(
56550
+ "Provider-specific fields: inspect result.toolResponse.rawV2 and its observed envelope. Prefer the declared getters above."
56551
+ );
56183
56552
  console.log(
56184
56553
  `More: deepline tools describe ${contract.toolId} --pricing-only | --schema-only | --examples-only | --getters-only | --json`
56185
56554
  );
@@ -56435,7 +56804,7 @@ function toolMetadataJsonForDescribe(tool, requestedToolId) {
56435
56804
  runtimeOutputHelp: {
56436
56805
  contract: "tools describe shows declared schema and Deepline getters; it is not an observed provider response.",
56437
56806
  getterScope: "extractedValues/extractedLists .get() only works for declared Deepline getters listed in usageGuidance.toolExecutionResult.",
56438
- rawToolResponse: "Use toolExecutionResult.toolResponse.raw for provider/tool-specific scalar fields, fields in outputSchema that are not declared getters, and debugging. For declared row/list outputs, use extractedLists.<name>.get(); raw row arrays may be inline previews.",
56807
+ rawToolResponse: "Use toolExecutionResult.toolResponse.rawV2 for provider/tool-specific scalar fields, fields in outputSchema that are not declared getters, and debugging. Inspect the observed response envelope before selecting nested fields. For declared row/list outputs, use extractedLists.<name>.get().",
56439
56808
  invalidGetterHint: "If TypeScript says an extractedValues/extractedLists property does not exist, that field is not a declared Deepline getter.",
56440
56809
  observeActualShape: observedOutputCommand,
56441
56810
  observedOutput: observedOutputCommand,
@@ -56457,14 +56826,18 @@ function usageGuidanceWithAccessDefaults(usageGuidance) {
56457
56826
  },
56458
56827
  extractedValues: {
56459
56828
  expression: "toolExecutionResult.extractedValues.<name>.get()",
56460
- meaning: "Declared Deepline scalar extractors only."
56829
+ meaning: "Declared Deepline scalar or normalized object extractors only."
56461
56830
  },
56831
+ ...existingAccess,
56462
56832
  rawToolResponse: {
56463
- expression: "toolExecutionResult.toolResponse.raw",
56464
- meaning: "Raw tool response for provider/tool-specific scalar fields and bounded debugging. Declared row/list outputs should use extractedLists.<name>.get(); raw row arrays may be inline previews."
56833
+ expression: "toolExecutionResult.toolResponse.rawV2",
56834
+ meaning: "Complete parsed and scrubbed provider response for provider/tool-specific scalar fields and debugging. Inspect its envelope before selecting nested fields. Declared row/list outputs should use extractedLists.<name>.get()."
56835
+ },
56836
+ canonicalToolResponse: {
56837
+ expression: "toolExecutionResult.toolResponse.rawV2",
56838
+ meaning: "Complete parsed and scrubbed provider response, including envelope siblings, pagination, and metadata."
56465
56839
  },
56466
- invalidGetterHint: "If TypeScript says an extractedValues/extractedLists property does not exist, that field is not a declared Deepline getter; use toolResponse.raw for provider/tool-specific scalar fields, and extractedLists.<name>.get() for declared row/list outputs.",
56467
- ...existingAccess
56840
+ invalidGetterHint: "If TypeScript says an extractedValues/extractedLists property does not exist, that field is not a declared Deepline getter; inspect toolResponse.rawV2 for provider/tool-specific scalar fields, and use extractedLists.<name>.get() for declared row/list outputs."
56468
56841
  }
56469
56842
  };
56470
56843
  }