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
package/dist/cli/index.js CHANGED
@@ -1973,6 +1973,9 @@ function playTriggerConfigPath(playName) {
1973
1973
  return `/api/v2/plays/${encodeURIComponent(playName)}/triggers`;
1974
1974
  }
1975
1975
 
1976
+ // src/csv-header-matching.ts
1977
+ 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>"}}.';
1978
+
1976
1979
  // src/pagination.ts
1977
1980
  async function* iterateCursorPages(fetchPage) {
1978
1981
  let cursor = null;
@@ -3512,7 +3515,7 @@ var SDK_RELEASE = {
3512
3515
  // getters keep their established compatibility behavior.
3513
3516
  // 0.3.1 deprecated the legacy `deepline enrich` command in favor of Plays.
3514
3517
  // 0.3.90 is the first deliberately versioned SDK release for API v3.
3515
- version: "0.3.279",
3518
+ version: "0.3.281",
3516
3519
  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.",
3517
3520
  packageCapabilities: {
3518
3521
  updatePreferences: 1
@@ -4167,7 +4170,7 @@ function applyExplicitHeaders(headers, explicit) {
4167
4170
  for (const existing of Object.keys(headers)) {
4168
4171
  if (existing.toLowerCase() === name) delete headers[existing];
4169
4172
  }
4170
- headers[name] = value;
4173
+ headers[rawName.trim()] = value;
4171
4174
  }
4172
4175
  return headers;
4173
4176
  }
@@ -4255,7 +4258,7 @@ var HttpClient = class {
4255
4258
  }
4256
4259
  }
4257
4260
  authHeaders(extra) {
4258
- const headers = {
4261
+ const transportHeaders = {
4259
4262
  Authorization: `Bearer ${this.config.apiKey}`,
4260
4263
  "User-Agent": `deepline-ts-sdk/${SDK_VERSION}`,
4261
4264
  "X-Deepline-Client-Family": "sdk",
@@ -4264,10 +4267,9 @@ var HttpClient = class {
4264
4267
  "X-Deepline-CLI-Version": SDK_VERSION,
4265
4268
  "X-Deepline-SDK-Version": SDK_VERSION,
4266
4269
  "X-Deepline-API-Contract": SDK_API_CONTRACT,
4267
- "X-Deepline-Run-Result-Shape": "canonical",
4268
- ...extra,
4269
- ...deploymentProtectionHeaders()
4270
+ "X-Deepline-Run-Result-Shape": "canonical"
4270
4271
  };
4272
+ const headers = deploymentProtectionHeaders();
4271
4273
  const skillsVersion = this.readSkillsVersionHeader();
4272
4274
  if (skillsVersion) {
4273
4275
  headers["X-Deepline-Skills-Version"] = skillsVersion;
@@ -4313,7 +4315,13 @@ var HttpClient = class {
4313
4315
  if (coordinatorInternalToken?.trim() && (coordinatorUrl?.trim() || workerCallbackUrl?.trim() || runtimeTestFault?.trim() || absurdReleaseOverride?.trim() || preferredReceiptGatewayMachineId?.trim())) {
4314
4316
  headers[COORDINATOR_INTERNAL_TOKEN_HEADER] = coordinatorInternalToken.trim();
4315
4317
  }
4316
- return applyExplicitHeaders(headers, this.config.headers);
4318
+ return applyExplicitHeaders(
4319
+ applyExplicitHeaders(
4320
+ applyExplicitHeaders(transportHeaders, extra),
4321
+ headers
4322
+ ),
4323
+ this.config.headers
4324
+ );
4317
4325
  }
4318
4326
  /**
4319
4327
  * Send an HTTP request with automatic retries and error handling.
@@ -4337,7 +4345,7 @@ var HttpClient = class {
4337
4345
  let networkPhase = "before_request";
4338
4346
  const headers = this.authHeaders(options?.headers);
4339
4347
  if (options?.body !== void 0) {
4340
- headers["Content-Type"] = "application/json";
4348
+ applyExplicitHeaders(headers, { "Content-Type": "application/json" });
4341
4349
  }
4342
4350
  let lastError = null;
4343
4351
  const candidateUrls = options?.exactUrlOnly ? [url] : buildCandidateUrls(url);
@@ -4596,7 +4604,7 @@ var HttpClient = class {
4596
4604
  ...options?.headers
4597
4605
  });
4598
4606
  if (options?.body !== void 0) {
4599
- headers["Content-Type"] = "application/json";
4607
+ applyExplicitHeaders(headers, { "Content-Type": "application/json" });
4600
4608
  }
4601
4609
  let lastError = null;
4602
4610
  for (const candidateUrl of buildCandidateUrls(url)) {
@@ -5638,6 +5646,182 @@ var RUN_EVENT_SEARCH_FALLBACK_KIND_SQL_LITERAL = sqlStringLiteral(
5638
5646
  RUN_EVENT_SEARCH_FALLBACK_KIND
5639
5647
  );
5640
5648
 
5649
+ // ../play-data-plane/runtime-sheet-orm.ts
5650
+ var RUNTIME_SHEET_CELL_META_COLUMN = {
5651
+ name: "_cell_meta",
5652
+ dataType: "jsonb",
5653
+ nullable: "NO",
5654
+ defaultSql: "'{}'::jsonb"
5655
+ };
5656
+ var RUNTIME_SHEET_COLUMN_CONTRACTS = [
5657
+ {
5658
+ name: "_key",
5659
+ sqlType: "text",
5660
+ dataType: "text",
5661
+ nullable: "NO",
5662
+ defaultSql: null,
5663
+ repairable: false,
5664
+ requiresDefault: false
5665
+ },
5666
+ {
5667
+ name: "_status",
5668
+ sqlType: "text NOT NULL",
5669
+ dataType: "text",
5670
+ nullable: "NO",
5671
+ defaultSql: null,
5672
+ repairable: false,
5673
+ requiresDefault: false
5674
+ },
5675
+ {
5676
+ name: "_run_id",
5677
+ sqlType: "text",
5678
+ dataType: "text",
5679
+ nullable: "YES",
5680
+ defaultSql: null,
5681
+ repairable: true,
5682
+ requiresDefault: false
5683
+ },
5684
+ {
5685
+ name: "_error",
5686
+ sqlType: "text",
5687
+ dataType: "text",
5688
+ nullable: "YES",
5689
+ defaultSql: null,
5690
+ repairable: true,
5691
+ requiresDefault: false
5692
+ },
5693
+ {
5694
+ name: "_stage",
5695
+ sqlType: "text",
5696
+ dataType: "text",
5697
+ nullable: "YES",
5698
+ defaultSql: null,
5699
+ repairable: true,
5700
+ requiresDefault: false
5701
+ },
5702
+ {
5703
+ name: "_provider",
5704
+ sqlType: "text",
5705
+ dataType: "text",
5706
+ nullable: "YES",
5707
+ defaultSql: null,
5708
+ repairable: true,
5709
+ requiresDefault: false
5710
+ },
5711
+ {
5712
+ name: "_input_index",
5713
+ sqlType: "bigint",
5714
+ dataType: "bigint",
5715
+ nullable: "YES",
5716
+ defaultSql: null,
5717
+ repairable: true,
5718
+ requiresDefault: false
5719
+ },
5720
+ {
5721
+ name: "_attempt_id",
5722
+ sqlType: "text",
5723
+ dataType: "text",
5724
+ nullable: "YES",
5725
+ defaultSql: null,
5726
+ repairable: true,
5727
+ requiresDefault: false
5728
+ },
5729
+ {
5730
+ name: "_attempt_owner_run_id",
5731
+ sqlType: "text",
5732
+ dataType: "text",
5733
+ nullable: "YES",
5734
+ defaultSql: null,
5735
+ repairable: true,
5736
+ requiresDefault: false
5737
+ },
5738
+ {
5739
+ name: "_attempt_expires_at",
5740
+ sqlType: "timestamptz",
5741
+ dataType: "timestamp with time zone",
5742
+ nullable: "YES",
5743
+ defaultSql: null,
5744
+ repairable: true,
5745
+ requiresDefault: false
5746
+ },
5747
+ {
5748
+ name: "_attempt_seq",
5749
+ sqlType: "integer",
5750
+ dataType: "integer",
5751
+ nullable: "YES",
5752
+ defaultSql: null,
5753
+ repairable: true,
5754
+ requiresDefault: false
5755
+ },
5756
+ {
5757
+ name: "_write_version",
5758
+ sqlType: "bigint NOT NULL DEFAULT 0",
5759
+ dataType: "bigint",
5760
+ nullable: "NO",
5761
+ defaultSql: "0",
5762
+ repairable: true,
5763
+ requiresDefault: true
5764
+ },
5765
+ {
5766
+ name: "_writer_run_id",
5767
+ sqlType: "text",
5768
+ dataType: "text",
5769
+ nullable: "YES",
5770
+ defaultSql: null,
5771
+ repairable: true,
5772
+ requiresDefault: false
5773
+ },
5774
+ {
5775
+ name: "_created_at",
5776
+ sqlType: "timestamptz NOT NULL DEFAULT now()",
5777
+ dataType: "timestamp with time zone",
5778
+ nullable: "NO",
5779
+ defaultSql: "now()",
5780
+ repairable: true,
5781
+ requiresDefault: true
5782
+ },
5783
+ {
5784
+ name: "_updated_at",
5785
+ sqlType: "timestamptz NOT NULL DEFAULT now()",
5786
+ dataType: "timestamp with time zone",
5787
+ nullable: "NO",
5788
+ defaultSql: "now()",
5789
+ repairable: true,
5790
+ requiresDefault: true
5791
+ },
5792
+ {
5793
+ name: "_version",
5794
+ sqlType: "bigint NOT NULL",
5795
+ dataType: "bigint",
5796
+ nullable: "NO",
5797
+ defaultSql: null,
5798
+ defaultKind: "version_sequence",
5799
+ repairable: true,
5800
+ requiresDefault: true
5801
+ },
5802
+ {
5803
+ ...RUNTIME_SHEET_CELL_META_COLUMN,
5804
+ sqlType: `jsonb NOT NULL DEFAULT ${RUNTIME_SHEET_CELL_META_COLUMN.defaultSql}`,
5805
+ repairable: true,
5806
+ requiresDefault: true
5807
+ }
5808
+ ];
5809
+ var RUNTIME_SHEET_ATTEMPT_COLUMNS = RUNTIME_SHEET_COLUMN_CONTRACTS.filter(
5810
+ (column) => column.name.startsWith("_attempt_")
5811
+ ).map((column) => column.name);
5812
+ var RUNTIME_SHEET_WRITE_VERSION_COLUMNS = RUNTIME_SHEET_COLUMN_CONTRACTS.filter(
5813
+ (column) => column.name === "_write_version" || column.name === "_writer_run_id"
5814
+ ).map((column) => column.name);
5815
+ var RUNTIME_SHEET_TIMESTAMP_COLUMNS = RUNTIME_SHEET_COLUMN_CONTRACTS.filter(
5816
+ (column) => column.name === "_created_at" || column.name === "_updated_at"
5817
+ ).map((column) => column.name);
5818
+ var RUNTIME_SHEET_SYSTEM_COLUMNS = new Set(
5819
+ RUNTIME_SHEET_COLUMN_CONTRACTS.map((column) => column.name)
5820
+ );
5821
+ var RUNTIME_SHEET_REPAIRABLE_COLUMNS = RUNTIME_SHEET_COLUMN_CONTRACTS.filter(
5822
+ (column) => column.repairable
5823
+ );
5824
+
5641
5825
  // ../play-runtime/run-ledger.ts
5642
5826
  var TERMINAL_STATUS_BY_EVENT_TYPE = {
5643
5827
  [RUN_EVENT_KIND.runCompleted]: "completed",
@@ -7366,7 +7550,9 @@ var DeeplineClient = class _DeeplineClient {
7366
7550
  inputSchema: options?.compact ? this.compactSchema(play.inputSchema) : play.inputSchema ?? null,
7367
7551
  outputSchema: options?.compact ? this.compactSchema(play.outputSchema) : play.outputSchema ?? null,
7368
7552
  staticPipeline: isRecord4(play.staticPipeline) ? play.staticPipeline : isRecord4(play.currentRevision?.staticPipeline) ? play.currentRevision.staticPipeline : isRecord4(play.liveRevision?.staticPipeline) ? play.liveRevision.staticPipeline : null,
7369
- ...csvInput ? { csvInput } : {},
7553
+ ...csvInput ? {
7554
+ csvInput: { ...csvInput, headerMatching: CSV_HEADER_MATCHING_NOTE }
7555
+ } : {},
7370
7556
  ...rowOutputSchema ? { rowOutputSchema } : {},
7371
7557
  runCommand: runCommand2,
7372
7558
  examples: [runCommand2],
@@ -7579,7 +7765,7 @@ var DeeplineClient = class _DeeplineClient {
7579
7765
  /**
7580
7766
  * Execute a tool and return the standard execution envelope.
7581
7767
  *
7582
- * The `toolResponse.raw` field contains the raw tool response.
7768
+ * The `toolResponse.rawV2` field contains the complete parsed and scrubbed tool response.
7583
7769
  * `toolResponse.meta` contains tool/provider metadata.
7584
7770
  * Top-level fields such as `status`, `job_id`, and `billing` describe the
7585
7771
  * Deepline execution envelope.
@@ -12536,15 +12722,42 @@ async function handleBalance(options) {
12536
12722
  const lines = [`Balance: ${payload.balance ?? "(unknown)"} credits`];
12537
12723
  const temporaryHolds = payload.temporary_hold_credits;
12538
12724
  if (typeof temporaryHolds === "number" && temporaryHolds > 0) {
12539
- lines.push(
12540
- `Temporarily reserved: ${temporaryHolds} credits \u2014 not charged; unused credits are released after final usage is calculated.`
12541
- );
12725
+ lines.push(`Open reservation exposure: ${temporaryHolds} credits.`);
12542
12726
  } else if (temporaryHolds === null) {
12543
12727
  lines.push("Temporary reservation status is temporarily unavailable.");
12544
12728
  }
12545
12729
  if (payload.temporary_hold_credits_truncated === true) {
12546
12730
  lines.push("Temporary reservation total may be incomplete.");
12547
12731
  }
12732
+ if (typeof payload.estimated_hold_credits === "number") {
12733
+ lines.push(
12734
+ `Estimated holds: ${payload.estimated_hold_credits} credits \u2014 final usage is not recorded yet.`
12735
+ );
12736
+ }
12737
+ if (typeof payload.incurred_unsettled_credits === "number") {
12738
+ lines.push(
12739
+ `Incurred, awaiting settlement: ${payload.incurred_unsettled_credits} credits.`
12740
+ );
12741
+ }
12742
+ if (typeof payload.pending_wallet_debit_credits === "number") {
12743
+ lines.push(
12744
+ `Pending wallet debit: ${payload.pending_wallet_debit_credits} credits \u2014 excludes amounts already debited for funded holds.`
12745
+ );
12746
+ }
12747
+ if (typeof payload.pending_wallet_refund_credits === "number" && payload.pending_wallet_refund_credits > 0) {
12748
+ lines.push(
12749
+ `Pending wallet refund: ${payload.pending_wallet_refund_credits} credits.`
12750
+ );
12751
+ }
12752
+ if (payload.exposure_status === "partial") {
12753
+ lines.push(
12754
+ "Exposure amounts are lower bounds: some reservations are unpriced or the scan is incomplete."
12755
+ );
12756
+ } else if (payload.exposure_status !== "complete") {
12757
+ lines.push(
12758
+ "The estimated and incurred usage breakdown is temporarily unavailable."
12759
+ );
12760
+ }
12548
12761
  if (status === "no_billing") {
12549
12762
  lines.push(
12550
12763
  "Billing: No billing account or payment method set up for this workspace."
@@ -25440,7 +25653,7 @@ async function traceCliSpan(phase, fields2, run) {
25440
25653
  }
25441
25654
 
25442
25655
  // src/cli/play-check-hints.ts
25443
- 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.";
25656
+ 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.";
25444
25657
  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()`.";
25445
25658
  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.";
25446
25659
  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.";
@@ -31931,6 +32144,7 @@ async function fetchBackingDatasetRows(input2) {
31931
32144
  return null;
31932
32145
  }
31933
32146
  const sheetRows = [];
32147
+ const seenEnvelopeKeys = /* @__PURE__ */ new Set();
31934
32148
  let offset = 0;
31935
32149
  let settledTotal = null;
31936
32150
  while (true) {
@@ -31942,6 +32156,27 @@ async function fetchBackingDatasetRows(input2) {
31942
32156
  offset,
31943
32157
  rowMode: "all"
31944
32158
  });
32159
+ for (const row of page.rows) {
32160
+ const key = readRecord(getRecordField(row, "data")) ? getStringField(row, "key") : null;
32161
+ if (key === null) continue;
32162
+ if (seenEnvelopeKeys.has(key)) {
32163
+ const activeRun = !TERMINAL_PLAY_STATUSES.has(input2.status.status);
32164
+ const waitCommand = `${input2.retryCommand} --wait`;
32165
+ throw new DeeplineError(
32166
+ "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}`),
32167
+ void 0,
32168
+ "RUN_EXPORT_NOT_READY",
32169
+ {
32170
+ runId: input2.status.runId,
32171
+ reason: "unstable_pagination",
32172
+ tableNamespace,
32173
+ retry_command: input2.retryCommand,
32174
+ ...activeRun ? { wait_command: waitCommand, do_not_rerun: true } : {}
32175
+ }
32176
+ );
32177
+ }
32178
+ seenEnvelopeKeys.add(key);
32179
+ }
31945
32180
  sheetRows.push(...page.rows);
31946
32181
  const summaryTotal = page.summary?.stats?.total;
31947
32182
  if (typeof summaryTotal === "number" && Number.isFinite(summaryTotal)) {
@@ -31957,15 +32192,23 @@ async function fetchBackingDatasetRows(input2) {
31957
32192
  (row) => Boolean(row) && typeof row === "object" && !Array.isArray(row)
31958
32193
  )
31959
32194
  );
31960
- const rows = sheetRows.map((row) => {
31961
- const data = exportableSheetRow(row);
31962
- return data && withError ? {
31963
- ...data,
31964
- [TABLE_EXPORT_ERROR_COLUMN]: tableExportErrorCell(
31965
- row
31966
- )
31967
- } : data;
31968
- }).filter((row) => Boolean(row));
32195
+ const exportedRowOutcomes = { succeeded: 0, failed: 0, unconfirmed: 0 };
32196
+ const rows = sheetRows.flatMap((row) => {
32197
+ const exported = exportableSheetRow(row);
32198
+ if (!exported) return [];
32199
+ const status = readRecord(getRecordField(row, "data")) ? getStringField(row, "status") : null;
32200
+ if (status === "completed") exportedRowOutcomes.succeeded += 1;
32201
+ else if (status === "failed") exportedRowOutcomes.failed += 1;
32202
+ else exportedRowOutcomes.unconfirmed += 1;
32203
+ return [
32204
+ withError ? {
32205
+ ...exported,
32206
+ [TABLE_EXPORT_ERROR_COLUMN]: tableExportErrorCell(
32207
+ row
32208
+ )
32209
+ } : exported
32210
+ ];
32211
+ });
31969
32212
  const hasCompleteSettledPrefix = acceptsSettledRowsAsCompleteExport(input2.status) && settledTotal !== null && // A zero-row run-scoped read is not a settled export when the returned
31970
32213
  // Dataset Handle advertised rows. That shape is the replay/reuse case:
31971
32214
  // the rows belong to another writer (or the projection has not caught up)
@@ -31980,7 +32223,8 @@ async function fetchBackingDatasetRows(input2) {
31980
32223
  source: `${input2.rowsInfo.source ?? "result.rows"} -> /api/v2/plays/${playName}/sheet?tableNamespace=${tableNamespace}`
31981
32224
  };
31982
32225
  }
31983
- if (rows.length < input2.rowsInfo.totalRows && !hasCompleteSettledPrefix) {
32226
+ const hasActiveSnapshot = !TERMINAL_PLAY_STATUSES.has(input2.status.status) && rows.length > 0 && exportedRowOutcomes.unconfirmed === 0;
32227
+ if (rows.length < input2.rowsInfo.totalRows && !hasCompleteSettledPrefix && !hasActiveSnapshot) {
31984
32228
  return null;
31985
32229
  }
31986
32230
  const columns = mergeExportColumns(
@@ -31992,7 +32236,10 @@ async function fetchBackingDatasetRows(input2) {
31992
32236
  rows,
31993
32237
  columns,
31994
32238
  totalRows: rows.length,
32239
+ // All pages of the selected snapshot were fetched. The CLI receipt
32240
+ // independently marks an active run's export as partial.
31995
32241
  complete: true,
32242
+ exportedRowOutcomes,
31996
32243
  currentTable: void 0,
31997
32244
  source: `${input2.rowsInfo.source ?? "result.rows"} -> /api/v2/plays/${playName}/sheet?tableNamespace=${tableNamespace}`
31998
32245
  };
@@ -32033,10 +32280,30 @@ function assertDatasetHasExportableRows(input2) {
32033
32280
  const inspectCommand = `deepline runs get ${input2.status.runId} --full --json`;
32034
32281
  const retryCommand = runExportRetryCommand(
32035
32282
  input2.status.runId,
32036
- "output.csv",
32037
- datasetLabel
32283
+ input2.outPath ?? "output.csv",
32284
+ datasetLabel,
32285
+ input2.format ? { format: input2.format } : void 0
32038
32286
  );
32039
32287
  const currentTableQueryCommand2 = input2.rowsInfo.currentTableQueryCommand;
32288
+ if (!TERMINAL_PLAY_STATUSES.has(input2.status.status)) {
32289
+ const waitCommand = `${retryCommand} --wait`;
32290
+ throw new DeeplineError(
32291
+ `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.`,
32292
+ void 0,
32293
+ "RUN_EXPORT_EMPTY",
32294
+ {
32295
+ runId: input2.status.runId,
32296
+ dataset: datasetLabel,
32297
+ runStatus,
32298
+ guidance: {
32299
+ wait_command: waitCommand,
32300
+ inspect_command: inspectCommand,
32301
+ do_not_rerun: true,
32302
+ reason: "The run is still active and has no accepted rows in this dataset."
32303
+ }
32304
+ }
32305
+ );
32306
+ }
32040
32307
  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.`;
32041
32308
  throw new DeeplineError(
32042
32309
  `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."),
@@ -32173,16 +32440,23 @@ ${commands.join("\n")}`,
32173
32440
  }
32174
32441
  const attempts = Math.max(1, Math.trunc(options.attempts ?? 1));
32175
32442
  const retryDelayMs = Math.max(0, Math.trunc(options.retryDelayMs ?? 0));
32443
+ const retryCommand = runExportRetryCommand(
32444
+ status.runId,
32445
+ outPath,
32446
+ options.datasetPath ?? rowsInfo.source,
32447
+ options
32448
+ );
32176
32449
  for (let attempt = 1; attempt <= attempts; attempt += 1) {
32177
32450
  let fetchedRowsInfo = null;
32178
32451
  try {
32179
32452
  fetchedRowsInfo = await fetchBackingDatasetRows({
32180
32453
  client: client2,
32181
32454
  status,
32182
- rowsInfo
32455
+ rowsInfo,
32456
+ retryCommand
32183
32457
  });
32184
32458
  } catch (error) {
32185
- if (error instanceof DeeplineError && error.code === "RUN_EXPORT_SCOPE_MISMATCH") {
32459
+ if (error instanceof DeeplineError && (error.code === "RUN_EXPORT_SCOPE_MISMATCH" || error.code === "RUN_EXPORT_NOT_READY")) {
32186
32460
  throw error;
32187
32461
  }
32188
32462
  if (!canExportPreview) {
@@ -32194,7 +32468,9 @@ ${commands.join("\n")}`,
32194
32468
  rowsInfo: fetchedRowsInfo,
32195
32469
  status,
32196
32470
  availableRows,
32197
- datasetPath: options.datasetPath
32471
+ datasetPath: options.datasetPath,
32472
+ outPath,
32473
+ format: options.format
32198
32474
  });
32199
32475
  return writeExport(guarded2);
32200
32476
  }
@@ -32203,7 +32479,9 @@ ${commands.join("\n")}`,
32203
32479
  rowsInfo,
32204
32480
  status,
32205
32481
  availableRows,
32206
- datasetPath: options.datasetPath
32482
+ datasetPath: options.datasetPath,
32483
+ outPath,
32484
+ format: options.format
32207
32485
  });
32208
32486
  return writeExport(guarded2);
32209
32487
  }
@@ -32212,15 +32490,11 @@ ${commands.join("\n")}`,
32212
32490
  }
32213
32491
  }
32214
32492
  if (!canExportPreview) {
32215
- const retryCommand = runExportRetryCommand(
32216
- status.runId,
32217
- outPath,
32218
- options.datasetPath ?? rowsInfo.source,
32219
- options
32220
- );
32221
32493
  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}`;
32494
+ const activeRun = !TERMINAL_PLAY_STATUSES.has(status.status);
32495
+ const waitCommand = `${retryCommand} --wait`;
32222
32496
  throw new DeeplineError(
32223
- `${previewReason}; the backing dataset was not ready to export yet. Retry with: ${retryCommand}`,
32497
+ `${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}`),
32224
32498
  void 0,
32225
32499
  "RUN_EXPORT_NOT_READY",
32226
32500
  {
@@ -32229,7 +32503,8 @@ ${commands.join("\n")}`,
32229
32503
  totalRows: rowsInfo.totalRows,
32230
32504
  tableNamespace: rowsInfo.tableNamespace ?? null,
32231
32505
  dataset: options.datasetPath ?? rowsInfo.source,
32232
- retry_command: retryCommand
32506
+ retry_command: retryCommand,
32507
+ ...activeRun ? { wait_command: waitCommand, do_not_rerun: true } : {}
32233
32508
  }
32234
32509
  );
32235
32510
  }
@@ -32237,7 +32512,9 @@ ${commands.join("\n")}`,
32237
32512
  rowsInfo,
32238
32513
  status,
32239
32514
  availableRows,
32240
- datasetPath: options.datasetPath
32515
+ datasetPath: options.datasetPath,
32516
+ outPath,
32517
+ format: options.format
32241
32518
  });
32242
32519
  return writeExport(guarded);
32243
32520
  }
@@ -32997,7 +33274,7 @@ function checkHintExpression(value) {
32997
33274
  return stringValue3(value).replace(/^toolExecutionResult\./, "result.");
32998
33275
  }
32999
33276
  function checkHintRawPath(value) {
33000
- return value?.replace(/^toolResponse\./, "result.toolResponse.");
33277
+ return value?.startsWith("toolResponse.rawV2") ? value.replace(/^toolResponse\./, "result.toolResponse.") : void 0;
33001
33278
  }
33002
33279
  function collectStaticPipelineToolIds(staticPipeline) {
33003
33280
  const seen = /* @__PURE__ */ new Set();
@@ -33042,7 +33319,7 @@ function toolGetterHintFromMetadata(toolId, tool) {
33042
33319
  toolId,
33043
33320
  lists,
33044
33321
  values,
33045
- raw: checkHintExpression(toolResponse.raw) || "result.toolResponse.raw"
33322
+ raw: checkHintExpression(toolResponse.rawV2) || "result.toolResponse.rawV2"
33046
33323
  };
33047
33324
  }
33048
33325
  async function buildToolGetterHints(client2, staticPipeline) {
@@ -33057,7 +33334,7 @@ async function buildToolGetterHints(client2, staticPipeline) {
33057
33334
  toolId,
33058
33335
  lists: [],
33059
33336
  values: [],
33060
- raw: "result.toolResponse.raw",
33337
+ raw: "result.toolResponse.rawV2",
33061
33338
  unavailable: error instanceof Error ? error.message : String(error)
33062
33339
  };
33063
33340
  }
@@ -35045,7 +35322,7 @@ async function handleRunStopAll(args) {
35045
35322
  async function handleRunExport(args) {
35046
35323
  const selection = parseJsonFields(args, "export");
35047
35324
  args = selection.args;
35048
- const usage2 = "Usage: deepline runs export <run-id> [--dataset result.rows] --out <path> [--format csv|json] [--metadata-out export.json] [--json]";
35325
+ 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]";
35049
35326
  let runId;
35050
35327
  try {
35051
35328
  runId = parseRunIdPositional(args, usage2);
@@ -35057,6 +35334,8 @@ async function handleRunExport(args) {
35057
35334
  let datasetPath = null;
35058
35335
  let metadataOutPath = null;
35059
35336
  let format = "csv";
35337
+ const wait = args.includes("--wait");
35338
+ let waitTimeoutMs = 3e5;
35060
35339
  for (let index = 0; index < args.length; index += 1) {
35061
35340
  const arg = args[index];
35062
35341
  if (arg === "--out" && args[index + 1]) {
@@ -35071,6 +35350,16 @@ async function handleRunExport(args) {
35071
35350
  metadataOutPath = (0, import_node_path19.resolve)(args[++index]);
35072
35351
  }
35073
35352
  if (arg === "--format") format = args[++index] ?? "";
35353
+ if (arg === "--timeout-ms") {
35354
+ waitTimeoutMs = parsePositiveInteger3(args[++index] ?? "", arg);
35355
+ if (!wait) {
35356
+ throw new DeeplineError(
35357
+ "--timeout-ms requires --wait.",
35358
+ void 0,
35359
+ "INVALID_ARGUMENT"
35360
+ );
35361
+ }
35362
+ }
35074
35363
  }
35075
35364
  if (!outPath) {
35076
35365
  console.error(usage2);
@@ -35091,7 +35380,33 @@ async function handleRunExport(args) {
35091
35380
  );
35092
35381
  }
35093
35382
  const client2 = new DeeplineClient();
35094
- const status = await client2.getPlayStatus(runId, { full: true });
35383
+ let status = await client2.getPlayStatus(runId, { full: true });
35384
+ if (wait && !TERMINAL_PLAY_STATUSES.has(status.status)) {
35385
+ const progress = createCliProgress(!argsWantJson(args));
35386
+ try {
35387
+ await waitForPlayCompletionByWatch({
35388
+ client: client2,
35389
+ playName: extractRunPlayName(status) ?? runId,
35390
+ workflowId: runId,
35391
+ jsonOutput: argsWantJson(args),
35392
+ emitLogs: false,
35393
+ waitTimeoutMs,
35394
+ startedAt: Date.now(),
35395
+ state: {
35396
+ emittedRunnerStarted: false,
35397
+ lastProgressSignature: null,
35398
+ lastProgressHeartbeatAt: 0,
35399
+ lastStatusHeartbeatAt: 0
35400
+ },
35401
+ progress
35402
+ });
35403
+ status = await client2.getPlayStatus(runId, { full: true });
35404
+ progress.complete();
35405
+ } catch (error) {
35406
+ progress.fail();
35407
+ throw error;
35408
+ }
35409
+ }
35095
35410
  const exportResult = await exportPlayStatusRows(client2, status, outPath, {
35096
35411
  datasetPath,
35097
35412
  format
@@ -35115,8 +35430,16 @@ async function handleRunExport(args) {
35115
35430
  { format }
35116
35431
  );
35117
35432
  const fileLocation = format === "json" ? { json_path: exportResult?.path ?? null } : { csv_path: exportResult?.path ?? null };
35433
+ const exportedRowOutcomes = exportResult?.rowsInfo.exportedRowOutcomes;
35434
+ const rowFailures = exportedRowOutcomes && exportedRowOutcomes.failed > 0 ? {
35435
+ count: exportedRowOutcomes.failed,
35436
+ message: "Failed rows can retain values from stages that completed earlier; those values do not prove the row succeeded.",
35437
+ inspectCommand: `deepline runs get ${status.runId} --json`
35438
+ } : null;
35118
35439
  const payload = {
35119
35440
  runId: status.runId,
35441
+ runStatus: status.status,
35442
+ isPartial: !TERMINAL_PLAY_STATUSES.has(status.status),
35120
35443
  datasets: identity ? [identity] : resolved ? [
35121
35444
  {
35122
35445
  ...resolved.datasetId ? { datasetId: resolved.datasetId } : {},
@@ -35128,18 +35451,30 @@ async function handleRunExport(args) {
35128
35451
  format,
35129
35452
  source,
35130
35453
  rowCount: exportResult?.rowsInfo.totalRows ?? null,
35454
+ ...exportedRowOutcomes ? { rowOutcomes: exportedRowOutcomes } : {},
35455
+ ...rowFailures ? { rowFailures } : {},
35131
35456
  columns: underscoreKeysLast(exportResult?.rowsInfo.columns ?? []),
35132
35457
  ...currentTableNotice ? { notice: currentTableNotice } : {},
35133
- ...metadataOutPath ? { metadata_path: metadataOutPath } : {}
35458
+ ...metadataOutPath ? { metadata_path: metadataOutPath } : {},
35459
+ ...!TERMINAL_PLAY_STATUSES.has(status.status) ? { completionCommand: `${exportCommand} --wait` } : {}
35134
35460
  };
35135
35461
  const lines = withRunNavigationLines(
35136
35462
  [
35137
35463
  `Exported ${status.runId} to ${exportResult?.path ?? outPath}`,
35464
+ ...!TERMINAL_PLAY_STATUSES.has(status.status) ? [
35465
+ `Partial export: run is ${status.status}; more rows may be saved.`,
35466
+ `Export after completion: ${exportCommand} --wait`
35467
+ ] : status.status === "failed" || status.status === "cancelled" ? [
35468
+ `Saved rows from a ${status.status} run. Inspect: deepline runs get ${status.runId} --json`
35469
+ ] : [],
35138
35470
  ...currentTableNotice ? [
35139
35471
  "Current shared dataset: this export may include writes from another run.",
35140
35472
  `This run's full returned output: ${currentTableNotice.full_run_output_command}`
35141
35473
  ] : [],
35142
- ...source ? [`source=${source}`] : []
35474
+ ...source ? [`source=${source}`] : [],
35475
+ ...rowFailures ? [
35476
+ `${rowFailures.count} failed row(s) included. Earlier saved values do not prove success. Inspect: ${rowFailures.inspectCommand}`
35477
+ ] : []
35143
35478
  ],
35144
35479
  status,
35145
35480
  payload.actions
@@ -35525,6 +35860,21 @@ function parsePlaySearchOptions(args) {
35525
35860
  function playSearchDisclaimer(scope) {
35526
35861
  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.";
35527
35862
  }
35863
+ function csvColumnLines(csvInput) {
35864
+ const rowSchema = isRecord7(csvInput.rowInputSchema) ? csvInput.rowInputSchema : {};
35865
+ const columns = isRecord7(rowSchema.properties) ? Object.keys(rowSchema.properties) : [];
35866
+ const required = new Set(
35867
+ Array.isArray(rowSchema.required) ? rowSchema.required.map(String) : []
35868
+ );
35869
+ const defaults = isRecord7(csvInput.defaultColumns) ? csvInput.defaultColumns : {};
35870
+ return [
35871
+ ...columns.map((column) => {
35872
+ const headers = [defaults[column]].flat().filter((header) => header && header !== column);
35873
+ return `${column}${required.has(column) ? " (required)" : ""}${headers.length > 0 ? `, default header: ${headers.join(" or ")}` : ""}`;
35874
+ }),
35875
+ CSV_HEADER_MATCHING_NOTE
35876
+ ];
35877
+ }
35528
35878
  function printPlayDescription(play) {
35529
35879
  const reference = formatPlayListReference(play);
35530
35880
  const labels = [
@@ -35545,6 +35895,12 @@ function printPlayDescription(play) {
35545
35895
  if (play.pinned) {
35546
35896
  console.log(" Pinned: yes");
35547
35897
  }
35898
+ if (play.csvInput) {
35899
+ console.log(" CSV columns:");
35900
+ for (const line of csvColumnLines(play.csvInput)) {
35901
+ console.log(` ${line}`);
35902
+ }
35903
+ }
35548
35904
  if (play.toolCategories?.length) {
35549
35905
  console.log(` Tool categories: ${play.toolCategories.join(", ")}`);
35550
35906
  }
@@ -37266,6 +37622,10 @@ Notes:
37266
37622
  --json controls stdout metadata, not the file format.
37267
37623
  --metadata-out writes the same export metadata object returned by --json,
37268
37624
  including the source dataset path and row/column metadata.
37625
+ An active run exports only the rows accepted so far; the receipt labels it
37626
+ partial. --wait observes the same run until it completes, fails, or is cancelled
37627
+ before exporting its saved rows. --timeout-ms bounds that wait (default 300000);
37628
+ a wait timeout leaves the run and destination file untouched.
37269
37629
 
37270
37630
  Examples:
37271
37631
  deepline runs export play/my-play/run/20260501t000000-000 --out output.csv
@@ -37273,11 +37633,15 @@ Examples:
37273
37633
  deepline runs export play/my-play/run/20260501t000000-000 --out output.csv --metadata-out output.meta.json
37274
37634
  deepline runs export play/my-play/run/20260501t000000-000 --out output.csv --json
37275
37635
  deepline runs export play/my-play/run/20260501t000000-000 --format json --out rows.json
37636
+ deepline runs export play/my-play/run/20260501t000000-000 --out rows.csv --wait --timeout-ms 600000
37276
37637
  `
37277
37638
  ).requiredOption("--out <path>", "Output file path").option("--format <format>", "File format: csv or json", "csv").option(
37278
37639
  "--dataset <path>",
37279
37640
  "Returned dataset handle path, such as result.rows"
37280
37641
  ).option("--metadata-out <path>", "Write export metadata JSON to a file").option(
37642
+ "--wait",
37643
+ "Wait for this run to reach a terminal status before export"
37644
+ ).option("--timeout-ms <ms>", "Maximum wait with --wait (default: 300000)").option(
37281
37645
  "--json [fields]",
37282
37646
  "JSON receipt; optionally select fields (dataset,datasets,actions). Does not filter exported rows"
37283
37647
  ).action(async (runId, options) => {
@@ -37289,6 +37653,8 @@ Examples:
37289
37653
  "--format",
37290
37654
  options.format,
37291
37655
  ...options.metadataOut ? ["--metadata-out", options.metadataOut] : [],
37656
+ ...options.wait ? ["--wait"] : [],
37657
+ ...options.timeoutMs ? ["--timeout-ms", options.timeoutMs] : [],
37292
37658
  ...jsonFieldArgs(options.json)
37293
37659
  ]);
37294
37660
  });
@@ -56027,6 +56393,9 @@ function printCompactToolContract(tool, requestedToolId) {
56027
56393
  }
56028
56394
  }
56029
56395
  console.log("");
56396
+ console.log(
56397
+ "Provider-specific fields: inspect result.toolResponse.rawV2 and its observed envelope. Prefer the declared getters above."
56398
+ );
56030
56399
  console.log(
56031
56400
  `More: deepline tools describe ${contract.toolId} --pricing-only | --schema-only | --examples-only | --getters-only | --json`
56032
56401
  );
@@ -56282,7 +56651,7 @@ function toolMetadataJsonForDescribe(tool, requestedToolId) {
56282
56651
  runtimeOutputHelp: {
56283
56652
  contract: "tools describe shows declared schema and Deepline getters; it is not an observed provider response.",
56284
56653
  getterScope: "extractedValues/extractedLists .get() only works for declared Deepline getters listed in usageGuidance.toolExecutionResult.",
56285
- 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.",
56654
+ 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().",
56286
56655
  invalidGetterHint: "If TypeScript says an extractedValues/extractedLists property does not exist, that field is not a declared Deepline getter.",
56287
56656
  observeActualShape: observedOutputCommand,
56288
56657
  observedOutput: observedOutputCommand,
@@ -56304,14 +56673,18 @@ function usageGuidanceWithAccessDefaults(usageGuidance) {
56304
56673
  },
56305
56674
  extractedValues: {
56306
56675
  expression: "toolExecutionResult.extractedValues.<name>.get()",
56307
- meaning: "Declared Deepline scalar extractors only."
56676
+ meaning: "Declared Deepline scalar or normalized object extractors only."
56308
56677
  },
56678
+ ...existingAccess,
56309
56679
  rawToolResponse: {
56310
- expression: "toolExecutionResult.toolResponse.raw",
56311
- 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."
56680
+ expression: "toolExecutionResult.toolResponse.rawV2",
56681
+ 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()."
56682
+ },
56683
+ canonicalToolResponse: {
56684
+ expression: "toolExecutionResult.toolResponse.rawV2",
56685
+ meaning: "Complete parsed and scrubbed provider response, including envelope siblings, pagination, and metadata."
56312
56686
  },
56313
- 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.",
56314
- ...existingAccess
56687
+ 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."
56315
56688
  }
56316
56689
  };
56317
56690
  }