deepline 0.1.225 → 0.1.227

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.
@@ -1,10 +1,22 @@
1
1
  import type { MapRowOutcome } from './durability-store';
2
+ import { stringifyPostgresJson } from './postgres-json';
3
+
4
+ export const RUNTIME_ROW_OUTPUT_NOT_JSON_SERIALIZABLE =
5
+ 'RUNTIME_ROW_OUTPUT_NOT_JSON_SERIALIZABLE';
6
+
7
+ const RUNTIME_ROW_OUTPUT_NOT_JSON_SERIALIZABLE_MESSAGE =
8
+ `${RUNTIME_ROW_OUTPUT_NOT_JSON_SERIALIZABLE}: Row output is not JSON-serializable. ` +
9
+ 'Remove BigInt values, circular references, and throwing toJSON implementations.';
2
10
 
3
11
  export type RuntimePreparedCompletedRow = {
4
12
  key: string;
5
13
  input_index: number | null;
6
14
  data_patch: Record<string, unknown>;
7
15
  cell_meta_patch: Record<string, unknown>;
16
+ /** Serialized once at the row boundary so SQL batching cannot re-run toJSON. */
17
+ data_patch_json: string;
18
+ /** Serialized once at the row boundary so SQL batching cannot re-run toJSON. */
19
+ cell_meta_patch_json: string;
8
20
  };
9
21
 
10
22
  export type RuntimePreparedFailedRow = RuntimePreparedCompletedRow & {
@@ -50,6 +62,51 @@ export function completedRuntimeCellMetaPatch(input: {
50
62
  return patch;
51
63
  }
52
64
 
65
+ function serializeRuntimeRowPatch(value: Record<string, unknown>): string {
66
+ const serialized = stringifyPostgresJson(value);
67
+ if (serialized === undefined) {
68
+ throw new TypeError('JSON.stringify returned undefined.');
69
+ }
70
+ return serialized;
71
+ }
72
+
73
+ function unserializableRuntimeRowFailure(input: {
74
+ key: string;
75
+ inputIndex: number | null;
76
+ runId: string;
77
+ outputFields: readonly string[];
78
+ }): RuntimePreparedFailedRow {
79
+ let cellMetaPatch = Object.fromEntries(
80
+ input.outputFields.map((field) => [
81
+ field,
82
+ {
83
+ status: 'failed',
84
+ runId: input.runId,
85
+ error: RUNTIME_ROW_OUTPUT_NOT_JSON_SERIALIZABLE_MESSAGE,
86
+ },
87
+ ]),
88
+ );
89
+ let cellMetaPatchJson: string;
90
+ try {
91
+ cellMetaPatchJson = serializeRuntimeRowPatch(cellMetaPatch);
92
+ } catch {
93
+ // Authored output field names can themselves collide after PostgreSQL JSON
94
+ // normalization. Preserve the explicit row failure instead of allowing
95
+ // diagnostic metadata to turn it back into a batch-fatal exception.
96
+ cellMetaPatch = {};
97
+ cellMetaPatchJson = '{}';
98
+ }
99
+ return {
100
+ key: input.key,
101
+ input_index: input.inputIndex,
102
+ data_patch: {},
103
+ cell_meta_patch: cellMetaPatch,
104
+ data_patch_json: '{}',
105
+ cell_meta_patch_json: cellMetaPatchJson,
106
+ error: RUNTIME_ROW_OUTPUT_NOT_JSON_SERIALIZABLE_MESSAGE,
107
+ };
108
+ }
109
+
53
110
  export function prepareRuntimeSheetRowTransitions(input: {
54
111
  rows: Iterable<MapRowOutcome>;
55
112
  runId: string;
@@ -62,12 +119,40 @@ export function prepareRuntimeSheetRowTransitions(input: {
62
119
  const failedRows: RuntimePreparedFailedRow[] = [];
63
120
  for (const row of input.rows) {
64
121
  if (!row.key) continue;
122
+ const inputIndex = normalizeRuntimeMapInputIndex(row.inputIndex);
123
+ let cellMetaPatch: Record<string, unknown>;
124
+ let dataPatchJson: string;
125
+ let cellMetaPatchJson: string;
126
+ try {
127
+ cellMetaPatch =
128
+ row.status === 'failed'
129
+ ? (row.cellMetaPatch ?? {})
130
+ : completedRuntimeCellMetaPatch({
131
+ runId: input.runId,
132
+ outputFields: input.outputFields,
133
+ rowPatch: row.cellMetaPatch,
134
+ });
135
+ dataPatchJson = serializeRuntimeRowPatch(row.data);
136
+ cellMetaPatchJson = serializeRuntimeRowPatch(cellMetaPatch);
137
+ } catch {
138
+ failedRows.push(
139
+ unserializableRuntimeRowFailure({
140
+ key: row.key,
141
+ inputIndex,
142
+ runId: input.runId,
143
+ outputFields: input.outputFields,
144
+ }),
145
+ );
146
+ continue;
147
+ }
65
148
  if (row.status === 'failed') {
66
149
  failedRows.push({
67
150
  key: row.key,
68
- input_index: normalizeRuntimeMapInputIndex(row.inputIndex),
151
+ input_index: inputIndex,
69
152
  data_patch: row.data,
70
- cell_meta_patch: row.cellMetaPatch ?? {},
153
+ cell_meta_patch: cellMetaPatch,
154
+ data_patch_json: dataPatchJson,
155
+ cell_meta_patch_json: cellMetaPatchJson,
71
156
  error:
72
157
  typeof row.error === 'string' && row.error.trim()
73
158
  ? row.error
@@ -77,14 +162,47 @@ export function prepareRuntimeSheetRowTransitions(input: {
77
162
  }
78
163
  completedRows.push({
79
164
  key: row.key,
80
- input_index: normalizeRuntimeMapInputIndex(row.inputIndex),
165
+ input_index: inputIndex,
81
166
  data_patch: row.data,
82
- cell_meta_patch: completedRuntimeCellMetaPatch({
83
- runId: input.runId,
84
- outputFields: input.outputFields,
85
- rowPatch: row.cellMetaPatch,
86
- }),
167
+ cell_meta_patch: cellMetaPatch,
168
+ data_patch_json: dataPatchJson,
169
+ cell_meta_patch_json: cellMetaPatchJson,
87
170
  });
88
171
  }
89
172
  return { completedRows, failedRows };
90
173
  }
174
+
175
+ /**
176
+ * Apply the row serialization boundary before a gateway-only runtime request.
177
+ * This prevents JSON.stringify on the transport envelope from turning one
178
+ * malformed row into a batch-fatal error before the gateway can persist the
179
+ * healthy siblings.
180
+ */
181
+ export function prepareRuntimeSheetRowsForJsonTransport(input: {
182
+ rows: Iterable<MapRowOutcome>;
183
+ runId: string;
184
+ outputFields: readonly string[];
185
+ }): MapRowOutcome[] {
186
+ const rows: MapRowOutcome[] = [];
187
+ for (const row of input.rows) {
188
+ const { completedRows, failedRows } = prepareRuntimeSheetRowTransitions({
189
+ rows: [row],
190
+ runId: input.runId,
191
+ outputFields: input.outputFields,
192
+ });
193
+ const prepared = completedRows[0] ?? failedRows[0];
194
+ if (!prepared) continue;
195
+ const failed = failedRows[0];
196
+ rows.push({
197
+ key: prepared.key,
198
+ inputIndex: prepared.input_index,
199
+ data: JSON.parse(prepared.data_patch_json) as Record<string, unknown>,
200
+ cellMetaPatch: JSON.parse(prepared.cell_meta_patch_json) as Record<
201
+ string,
202
+ unknown
203
+ >,
204
+ ...(failed ? { status: 'failed' as const, error: failed.error } : {}),
205
+ });
206
+ }
207
+ return rows;
208
+ }
@@ -13,6 +13,7 @@ export type PlayStepLifecycleEvent = {
13
13
  type: string;
14
14
  transition: 'started' | 'completed' | 'failed';
15
15
  at: number;
16
+ error?: string;
16
17
  };
17
18
 
18
19
  function isAutoStartedSetupNode(type: string): boolean {
@@ -191,7 +192,7 @@ export class PlayStepLifecycleTracker {
191
192
  }
192
193
  }
193
194
 
194
- markStartedFailed(at = this.now()): void {
195
+ markStartedFailed(at = this.now(), error?: string): void {
195
196
  for (let index = this.nodes.length - 1; index >= 0; index -= 1) {
196
197
  const node = this.nodes[index]!;
197
198
  const existing = this.getProgress()[node.nodeId];
@@ -202,6 +203,7 @@ export class PlayStepLifecycleTracker {
202
203
  type: node.type,
203
204
  transition: 'failed',
204
205
  at,
206
+ ...(error?.trim() ? { error: error.trim() } : {}),
205
207
  });
206
208
  return;
207
209
  }
package/dist/cli/index.js CHANGED
@@ -625,10 +625,10 @@ var SDK_RELEASE = {
625
625
  // 0.1.175 ships loud `deepline enrich` empty-waterfall reporting.
626
626
  // 0.1.220 deprecates SDK CLI versions below 0.1.219 and updates them
627
627
  // automatically without blocking their current command.
628
- version: "0.1.225",
628
+ version: "0.1.227",
629
629
  apiContract: "2026-06-dataset-handle-results-hard-cutover",
630
630
  supportPolicy: {
631
- latest: "0.1.225",
631
+ latest: "0.1.227",
632
632
  minimumSupported: "0.1.53",
633
633
  deprecatedBelow: "0.1.219",
634
634
  commandMinimumSupported: [
@@ -1348,6 +1348,9 @@ function resolveTimingWindow(input2) {
1348
1348
  };
1349
1349
  }
1350
1350
 
1351
+ // ../shared_libs/play-runtime/run-failure.ts
1352
+ var PUBLIC_FAILURE_TEXT_BYTE_LIMIT = 64 * 1024;
1353
+
1351
1354
  // ../shared_libs/play-runtime/run-terminal-source.ts
1352
1355
  var PLAY_RUN_LEDGER_EVENT_SOURCES = [
1353
1356
  "worker",
@@ -1576,6 +1579,7 @@ function normalizePlayRunLedgerSnapshot(value, fallback) {
1576
1579
  label: optionalString(rawStep.label),
1577
1580
  kind: optionalString(rawStep.kind),
1578
1581
  status,
1582
+ error: optionalNullableString(rawStep.error),
1579
1583
  artifactTableNamespace: optionalNullableString(
1580
1584
  rawStep.artifactTableNamespace
1581
1585
  ),
@@ -1752,6 +1756,7 @@ function buildSnapshotFromLedger(snapshot) {
1752
1756
  const nodeStates = snapshot.orderedStepIds.map((stepId) => snapshot.stepsById[stepId]).filter((step) => Boolean(step)).map((step) => ({
1753
1757
  nodeId: step.stepId,
1754
1758
  status: step.status,
1759
+ error: step.error ?? null,
1755
1760
  artifactTableNamespace: step.artifactTableNamespace ?? null,
1756
1761
  progress: step.progress ? {
1757
1762
  completed: step.progress.completed,
@@ -13758,6 +13763,13 @@ function formatPackageValueOutputLines(packaged) {
13758
13763
  }
13759
13764
  return lines;
13760
13765
  }
13766
+ function authoredPackageStackFrames(packaged) {
13767
+ const stack = readRecordArray(packaged.errors).map((entry) => typeof entry.stack === "string" ? entry.stack : null).find((candidate) => Boolean(candidate?.trim()));
13768
+ if (!stack) return [];
13769
+ return stack.split("\n").map((line) => line.trim()).filter((line) => line.startsWith("at ")).filter(
13770
+ (line) => !line.includes("/virtual/deepline-plays/") && !line.includes("/apps/play-runner/") && !line.includes("/shared_libs/play-runtime/") && !line.includes("node:internal")
13771
+ ).slice(0, 5);
13772
+ }
13761
13773
  function buildRunPackageTextLines(packaged) {
13762
13774
  const run = readRunPackageRun(packaged);
13763
13775
  const runId = typeof run.id === "string" ? run.id : "unknown";
@@ -13769,6 +13781,11 @@ function buildRunPackageTextLines(packaged) {
13769
13781
  const runError = typeof run.error === "string" && run.error.trim() ? run.error.trim() : null;
13770
13782
  if (runError && (status === "failed" || status === "cancelled")) {
13771
13783
  lines.push(` error: ${truncateErrorForDisplay(runError, runId)}`);
13784
+ const stackFrames = authoredPackageStackFrames(packaged);
13785
+ if (stackFrames.length > 0) {
13786
+ lines.push(" stack:");
13787
+ lines.push(...stackFrames.map((frame) => ` ${frame}`));
13788
+ }
13772
13789
  }
13773
13790
  const failedLogs = readRecord(packaged.failedLogs);
13774
13791
  const failedLogEntries = Array.isArray(failedLogs?.entries) ? failedLogs.entries.filter(
@@ -610,10 +610,10 @@ var SDK_RELEASE = {
610
610
  // 0.1.175 ships loud `deepline enrich` empty-waterfall reporting.
611
611
  // 0.1.220 deprecates SDK CLI versions below 0.1.219 and updates them
612
612
  // automatically without blocking their current command.
613
- version: "0.1.225",
613
+ version: "0.1.227",
614
614
  apiContract: "2026-06-dataset-handle-results-hard-cutover",
615
615
  supportPolicy: {
616
- latest: "0.1.225",
616
+ latest: "0.1.227",
617
617
  minimumSupported: "0.1.53",
618
618
  deprecatedBelow: "0.1.219",
619
619
  commandMinimumSupported: [
@@ -1333,6 +1333,9 @@ function resolveTimingWindow(input2) {
1333
1333
  };
1334
1334
  }
1335
1335
 
1336
+ // ../shared_libs/play-runtime/run-failure.ts
1337
+ var PUBLIC_FAILURE_TEXT_BYTE_LIMIT = 64 * 1024;
1338
+
1336
1339
  // ../shared_libs/play-runtime/run-terminal-source.ts
1337
1340
  var PLAY_RUN_LEDGER_EVENT_SOURCES = [
1338
1341
  "worker",
@@ -1561,6 +1564,7 @@ function normalizePlayRunLedgerSnapshot(value, fallback) {
1561
1564
  label: optionalString(rawStep.label),
1562
1565
  kind: optionalString(rawStep.kind),
1563
1566
  status,
1567
+ error: optionalNullableString(rawStep.error),
1564
1568
  artifactTableNamespace: optionalNullableString(
1565
1569
  rawStep.artifactTableNamespace
1566
1570
  ),
@@ -1737,6 +1741,7 @@ function buildSnapshotFromLedger(snapshot) {
1737
1741
  const nodeStates = snapshot.orderedStepIds.map((stepId) => snapshot.stepsById[stepId]).filter((step) => Boolean(step)).map((step) => ({
1738
1742
  nodeId: step.stepId,
1739
1743
  status: step.status,
1744
+ error: step.error ?? null,
1740
1745
  artifactTableNamespace: step.artifactTableNamespace ?? null,
1741
1746
  progress: step.progress ? {
1742
1747
  completed: step.progress.completed,
@@ -13787,6 +13792,13 @@ function formatPackageValueOutputLines(packaged) {
13787
13792
  }
13788
13793
  return lines;
13789
13794
  }
13795
+ function authoredPackageStackFrames(packaged) {
13796
+ const stack = readRecordArray(packaged.errors).map((entry) => typeof entry.stack === "string" ? entry.stack : null).find((candidate) => Boolean(candidate?.trim()));
13797
+ if (!stack) return [];
13798
+ return stack.split("\n").map((line) => line.trim()).filter((line) => line.startsWith("at ")).filter(
13799
+ (line) => !line.includes("/virtual/deepline-plays/") && !line.includes("/apps/play-runner/") && !line.includes("/shared_libs/play-runtime/") && !line.includes("node:internal")
13800
+ ).slice(0, 5);
13801
+ }
13790
13802
  function buildRunPackageTextLines(packaged) {
13791
13803
  const run = readRunPackageRun(packaged);
13792
13804
  const runId = typeof run.id === "string" ? run.id : "unknown";
@@ -13798,6 +13810,11 @@ function buildRunPackageTextLines(packaged) {
13798
13810
  const runError = typeof run.error === "string" && run.error.trim() ? run.error.trim() : null;
13799
13811
  if (runError && (status === "failed" || status === "cancelled")) {
13800
13812
  lines.push(` error: ${truncateErrorForDisplay(runError, runId)}`);
13813
+ const stackFrames = authoredPackageStackFrames(packaged);
13814
+ if (stackFrames.length > 0) {
13815
+ lines.push(" stack:");
13816
+ lines.push(...stackFrames.map((frame) => ` ${frame}`));
13817
+ }
13801
13818
  }
13802
13819
  const failedLogs = readRecord(packaged.failedLogs);
13803
13820
  const failedLogEntries = Array.isArray(failedLogs?.entries) ? failedLogs.entries.filter(
package/dist/index.d.mts CHANGED
@@ -3426,6 +3426,11 @@ type DatasetBuilder<InputRow extends object, OutputRow extends object> = {
3426
3426
  */
3427
3427
  run(options?: {
3428
3428
  description?: string;
3429
+ /**
3430
+ * `upsert` (default) returns every input row, reusing persisted work for
3431
+ * existing keys. `net_new` atomically inserts and returns only unseen keys.
3432
+ */
3433
+ mode?: 'upsert' | 'net_new';
3429
3434
  key?: (keyof InputRow & string) | readonly (keyof InputRow & string)[] | ((row: InputRow, index: number) => string | number | readonly unknown[]);
3430
3435
  }): Promise<PlayDataset<OutputRow>>;
3431
3436
  };
package/dist/index.d.ts CHANGED
@@ -3426,6 +3426,11 @@ type DatasetBuilder<InputRow extends object, OutputRow extends object> = {
3426
3426
  */
3427
3427
  run(options?: {
3428
3428
  description?: string;
3429
+ /**
3430
+ * `upsert` (default) returns every input row, reusing persisted work for
3431
+ * existing keys. `net_new` atomically inserts and returns only unseen keys.
3432
+ */
3433
+ mode?: 'upsert' | 'net_new';
3429
3434
  key?: (keyof InputRow & string) | readonly (keyof InputRow & string)[] | ((row: InputRow, index: number) => string | number | readonly unknown[]);
3430
3435
  }): Promise<PlayDataset<OutputRow>>;
3431
3436
  };
package/dist/index.js CHANGED
@@ -424,10 +424,10 @@ var SDK_RELEASE = {
424
424
  // 0.1.175 ships loud `deepline enrich` empty-waterfall reporting.
425
425
  // 0.1.220 deprecates SDK CLI versions below 0.1.219 and updates them
426
426
  // automatically without blocking their current command.
427
- version: "0.1.225",
427
+ version: "0.1.227",
428
428
  apiContract: "2026-06-dataset-handle-results-hard-cutover",
429
429
  supportPolicy: {
430
- latest: "0.1.225",
430
+ latest: "0.1.227",
431
431
  minimumSupported: "0.1.53",
432
432
  deprecatedBelow: "0.1.219",
433
433
  commandMinimumSupported: [
@@ -1147,6 +1147,9 @@ function resolveTimingWindow(input) {
1147
1147
  };
1148
1148
  }
1149
1149
 
1150
+ // ../shared_libs/play-runtime/run-failure.ts
1151
+ var PUBLIC_FAILURE_TEXT_BYTE_LIMIT = 64 * 1024;
1152
+
1150
1153
  // ../shared_libs/play-runtime/run-terminal-source.ts
1151
1154
  var PLAY_RUN_LEDGER_EVENT_SOURCES = [
1152
1155
  "worker",
@@ -1375,6 +1378,7 @@ function normalizePlayRunLedgerSnapshot(value, fallback) {
1375
1378
  label: optionalString(rawStep.label),
1376
1379
  kind: optionalString(rawStep.kind),
1377
1380
  status,
1381
+ error: optionalNullableString(rawStep.error),
1378
1382
  artifactTableNamespace: optionalNullableString(
1379
1383
  rawStep.artifactTableNamespace
1380
1384
  ),
@@ -1551,6 +1555,7 @@ function buildSnapshotFromLedger(snapshot) {
1551
1555
  const nodeStates = snapshot.orderedStepIds.map((stepId) => snapshot.stepsById[stepId]).filter((step) => Boolean(step)).map((step) => ({
1552
1556
  nodeId: step.stepId,
1553
1557
  status: step.status,
1558
+ error: step.error ?? null,
1554
1559
  artifactTableNamespace: step.artifactTableNamespace ?? null,
1555
1560
  progress: step.progress ? {
1556
1561
  completed: step.progress.completed,
package/dist/index.mjs CHANGED
@@ -354,10 +354,10 @@ var SDK_RELEASE = {
354
354
  // 0.1.175 ships loud `deepline enrich` empty-waterfall reporting.
355
355
  // 0.1.220 deprecates SDK CLI versions below 0.1.219 and updates them
356
356
  // automatically without blocking their current command.
357
- version: "0.1.225",
357
+ version: "0.1.227",
358
358
  apiContract: "2026-06-dataset-handle-results-hard-cutover",
359
359
  supportPolicy: {
360
- latest: "0.1.225",
360
+ latest: "0.1.227",
361
361
  minimumSupported: "0.1.53",
362
362
  deprecatedBelow: "0.1.219",
363
363
  commandMinimumSupported: [
@@ -1077,6 +1077,9 @@ function resolveTimingWindow(input) {
1077
1077
  };
1078
1078
  }
1079
1079
 
1080
+ // ../shared_libs/play-runtime/run-failure.ts
1081
+ var PUBLIC_FAILURE_TEXT_BYTE_LIMIT = 64 * 1024;
1082
+
1080
1083
  // ../shared_libs/play-runtime/run-terminal-source.ts
1081
1084
  var PLAY_RUN_LEDGER_EVENT_SOURCES = [
1082
1085
  "worker",
@@ -1305,6 +1308,7 @@ function normalizePlayRunLedgerSnapshot(value, fallback) {
1305
1308
  label: optionalString(rawStep.label),
1306
1309
  kind: optionalString(rawStep.kind),
1307
1310
  status,
1311
+ error: optionalNullableString(rawStep.error),
1308
1312
  artifactTableNamespace: optionalNullableString(
1309
1313
  rawStep.artifactTableNamespace
1310
1314
  ),
@@ -1481,6 +1485,7 @@ function buildSnapshotFromLedger(snapshot) {
1481
1485
  const nodeStates = snapshot.orderedStepIds.map((stepId) => snapshot.stepsById[stepId]).filter((step) => Boolean(step)).map((step) => ({
1482
1486
  nodeId: step.stepId,
1483
1487
  status: step.status,
1488
+ error: step.error ?? null,
1484
1489
  artifactTableNamespace: step.artifactTableNamespace ?? null,
1485
1490
  progress: step.progress ? {
1486
1491
  completed: step.progress.completed,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "deepline",
3
- "version": "0.1.225",
3
+ "version": "0.1.227",
4
4
  "description": "Deepline SDK + CLI — B2B data enrichment powered by durable cloud execution",
5
5
  "license": "MIT",
6
6
  "repository": {