deepline 0.1.22 → 0.1.24

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.
@@ -93,6 +93,10 @@ import {
93
93
  type CsvRenameOptions,
94
94
  } from '../../../shared_libs/play-runtime/csv-rename';
95
95
  import { coordinatorRequestHeaders } from '../../../shared_libs/play-runtime/coordinator-headers';
96
+ import type {
97
+ LiveNodeProgressMap,
98
+ LiveNodeProgressSnapshot,
99
+ } from './runtime/live-progress';
96
100
 
97
101
  // The play's default export. The bundler injects this — see bundle-play-file.ts.
98
102
  // eslint-disable-next-line @typescript-eslint/ban-ts-comment
@@ -496,9 +500,7 @@ function makeWorkerDataset<T extends Record<string, unknown>>(
496
500
  preview: plainRows,
497
501
  tableNamespace: name,
498
502
  ...(cacheSummary ? { cacheSummary } : {}),
499
- ...(workProgress
500
- ? { _metadata: { workProgress } }
501
- : {}),
503
+ ...(workProgress ? { _metadata: { workProgress } } : {}),
502
504
  };
503
505
  },
504
506
  enumerable: false,
@@ -521,22 +523,11 @@ type WorkflowRunOutput = {
521
523
  playName: string;
522
524
  result: unknown;
523
525
  outputRows: number;
526
+ liveLogs?: string[];
527
+ liveNodeProgress?: LiveNodeProgressMap;
524
528
  durationMs: number;
525
529
  };
526
530
 
527
- type LiveNodeProgressSnapshot = {
528
- completed?: number;
529
- total?: number;
530
- failed?: number;
531
- message?: string;
532
- updatedAt?: number;
533
- startedAt?: number;
534
- completedAt?: number;
535
- artifactTableNamespace?: string | null;
536
- };
537
-
538
- type LiveNodeProgressMap = Record<string, LiveNodeProgressSnapshot>;
539
-
540
531
  type WorkerCtxCallbacks = {
541
532
  onNodeProgress?: (input: {
542
533
  nodeId: string;
@@ -555,6 +546,12 @@ function recordRunnerPerfTrace(input: {
555
546
  extra?: Record<string, unknown>;
556
547
  }): void {
557
548
  if (!input.req.runId || !input.phase) return;
549
+ // Tool-level traces can fire once per row/provider step. Forwarding each one
550
+ // through the coordinator binding can consume Cloudflare's subrequest budget
551
+ // before large batched maps finish.
552
+ if (input.phase.startsWith('runner.tool.')) {
553
+ return;
554
+ }
558
555
  const payload = {
559
556
  ts: Date.now(),
560
557
  source: 'dynamic_worker' as const,
@@ -946,7 +943,8 @@ async function signalParentPlayTerminal(input: {
946
943
  }
947
944
  const text = await res.text().catch(() => '');
948
945
  throw new Error(
949
- text.slice(0, 800) || `Coordinator parent signal failed with ${res.status}.`,
946
+ text.slice(0, 800) ||
947
+ `Coordinator parent signal failed with ${res.status}.`,
950
948
  );
951
949
  }
952
950
  throw new Error(
@@ -2517,6 +2515,7 @@ async function persistCompletedMapRows(input: {
2517
2515
  ],
2518
2516
  runId: input.req.runId,
2519
2517
  userEmail: input.req.userEmail,
2518
+ preloadedDbSessions: input.req.preloadedDbSessions ?? null,
2520
2519
  });
2521
2520
  }
2522
2521
 
@@ -2542,6 +2541,7 @@ async function prepareMapRows(input: {
2542
2541
  rows: input.rows.map((row) => ({ ...row })),
2543
2542
  runId: input.req.runId,
2544
2543
  userEmail: input.req.userEmail,
2544
+ preloadedDbSessions: input.req.preloadedDbSessions ?? null,
2545
2545
  });
2546
2546
  return {
2547
2547
  inserted: result.inserted,
@@ -3091,8 +3091,7 @@ function createMinimalWorkerCtx(
3091
3091
  executedCellMetaPatches[executedIndex],
3092
3092
  }
3093
3093
  : {}),
3094
- __deeplineRowKey:
3095
- uniqueRowsToExecuteEntries[executedIndex]!.rowKey,
3094
+ __deeplineRowKey: uniqueRowsToExecuteEntries[executedIndex]!.rowKey,
3096
3095
  })),
3097
3096
  });
3098
3097
  };
@@ -3326,7 +3325,11 @@ function createMinimalWorkerCtx(
3326
3325
  req,
3327
3326
  phase: 'runner.map.total',
3328
3327
  ms: nowMs() - mapStartedAt,
3329
- extra: { mapName: name, rowsWritten: totalRowsWritten, streaming: true },
3328
+ extra: {
3329
+ mapName: name,
3330
+ rowsWritten: totalRowsWritten,
3331
+ streaming: true,
3332
+ },
3330
3333
  });
3331
3334
  return dataset;
3332
3335
  }
@@ -3360,7 +3363,11 @@ function createMinimalWorkerCtx(
3360
3363
  req,
3361
3364
  phase: 'runner.map.total',
3362
3365
  ms: nowMs() - mapStartedAt,
3363
- extra: { mapName: name, rowsWritten: totalRowsWritten, streaming: false },
3366
+ extra: {
3367
+ mapName: name,
3368
+ rowsWritten: totalRowsWritten,
3369
+ streaming: false,
3370
+ },
3364
3371
  });
3365
3372
  return dataset;
3366
3373
  }
@@ -4176,6 +4183,7 @@ async function executeRunRequest(
4176
4183
  phase: 'runner.terminal_status_update',
4177
4184
  ms: nowMs() - terminalUpdateStartedAt,
4178
4185
  });
4186
+
4179
4187
  const billingStartedAt = nowMs();
4180
4188
  await finalizeWorkerComputeBilling({
4181
4189
  req,
@@ -4214,6 +4222,8 @@ async function executeRunRequest(
4214
4222
  playName: req.playName,
4215
4223
  result: serializedResult,
4216
4224
  outputRows: inferOutputRows(serializedResult),
4225
+ liveLogs,
4226
+ liveNodeProgress: liveNodeProgressSnapshot(),
4217
4227
  durationMs: nowMs() - startedAt,
4218
4228
  };
4219
4229
  } catch (error) {
@@ -4429,6 +4439,7 @@ async function persistResultDatasets(
4429
4439
  rows: dataset.rows,
4430
4440
  runId: req.runId,
4431
4441
  userEmail: req.userEmail,
4442
+ preloadedDbSessions: req.preloadedDbSessions ?? null,
4432
4443
  });
4433
4444
  }
4434
4445
  }
@@ -4515,14 +4526,16 @@ function serializeValue(value: unknown, depth: number): unknown {
4515
4526
  ? (value as unknown as { __deeplineCacheSummary: string })
4516
4527
  .__deeplineCacheSummary
4517
4528
  : null;
4518
- const workProgress =
4519
- isRecord(
4520
- (value as unknown as { __deeplineWorkProgress?: unknown })
4521
- .__deeplineWorkProgress,
4522
- )
4523
- ? (value as unknown as { __deeplineWorkProgress: Record<string, unknown> })
4524
- .__deeplineWorkProgress
4525
- : null;
4529
+ const workProgress = isRecord(
4530
+ (value as unknown as { __deeplineWorkProgress?: unknown })
4531
+ .__deeplineWorkProgress,
4532
+ )
4533
+ ? (
4534
+ value as unknown as {
4535
+ __deeplineWorkProgress: Record<string, unknown>;
4536
+ }
4537
+ ).__deeplineWorkProgress
4538
+ : null;
4526
4539
  const previewRows = value
4527
4540
  .slice(0, 5)
4528
4541
  .map((row) => serializeValue(row, depth + 1))
@@ -4540,9 +4553,7 @@ function serializeValue(value: unknown, depth: number): unknown {
4540
4553
  preview: previewRows,
4541
4554
  tableNamespace,
4542
4555
  ...(cacheSummary ? { cacheSummary } : {}),
4543
- ...(workProgress
4544
- ? { _metadata: { workProgress } }
4545
- : {}),
4556
+ ...(workProgress ? { _metadata: { workProgress } } : {}),
4546
4557
  };
4547
4558
  }
4548
4559
  return value.map((entry) => serializeValue(entry, depth + 1));
@@ -0,0 +1,18 @@
1
+ export type LiveNodeProgressSnapshot = {
2
+ completed?: number;
3
+ total?: number;
4
+ failed?: number;
5
+ message?: string;
6
+ updatedAt?: number;
7
+ startedAt?: number;
8
+ completedAt?: number;
9
+ artifactTableNamespace?: string | null;
10
+ };
11
+
12
+ export type LiveNodeProgressMap = Record<string, LiveNodeProgressSnapshot>;
13
+
14
+ export function sanitizeLiveLogLines(value: unknown): string[] | null {
15
+ return Array.isArray(value)
16
+ ? value.filter((line): line is string => typeof line === 'string')
17
+ : null;
18
+ }
@@ -67,6 +67,26 @@ import type { PlayCompilerManifest } from '../../shared_libs/plays/compiler-mani
67
67
 
68
68
  const TERMINAL_PLAY_STATUSES = new Set(['completed', 'failed', 'cancelled']);
69
69
  const INCLUDE_TOOL_METADATA_HEADER = 'x-deepline-include-tool-metadata';
70
+ const COMPILE_MANIFEST_RETRY_DELAYS_MS = [250, 1_000];
71
+
72
+ function sleep(ms: number): Promise<void> {
73
+ return new Promise((resolve) => setTimeout(resolve, ms));
74
+ }
75
+
76
+ function isTransientCompileManifestError(error: unknown): boolean {
77
+ if (error instanceof DeeplineError && typeof error.statusCode === 'number') {
78
+ return (
79
+ error.statusCode === 408 ||
80
+ error.statusCode === 425 ||
81
+ error.statusCode === 499 ||
82
+ (error.statusCode >= 500 && error.statusCode < 600)
83
+ );
84
+ }
85
+ const message = error instanceof Error ? error.message : String(error);
86
+ return /fetch failed|connection (?:closed|reset|terminated)|socket hang up|econnreset|etimedout|eai_again|abort/i.test(
87
+ message,
88
+ );
89
+ }
70
90
 
71
91
  type ExecuteToolRawOptions = {
72
92
  includeToolMetadata?: boolean;
@@ -759,10 +779,24 @@ export class DeeplineClient {
759
779
  artifact: Record<string, unknown>;
760
780
  importedPlayDependencies?: PlayCompilerManifest[];
761
781
  }): Promise<PlayCompilerManifest> {
762
- const response = await this.http.post<{
763
- compilerManifest: PlayCompilerManifest;
764
- }>('/api/v2/plays/compile-manifest', input);
765
- return response.compilerManifest;
782
+ const retryDelays = COMPILE_MANIFEST_RETRY_DELAYS_MS.slice(
783
+ 0,
784
+ Math.max(0, this.config.maxRetries),
785
+ );
786
+ for (let attempt = 0; ; attempt += 1) {
787
+ try {
788
+ const response = await this.http.post<{
789
+ compilerManifest: PlayCompilerManifest;
790
+ }>('/api/v2/plays/compile-manifest', input);
791
+ return response.compilerManifest;
792
+ } catch (error) {
793
+ const delayMs = retryDelays[attempt];
794
+ if (delayMs === undefined || !isTransientCompileManifestError(error)) {
795
+ throw error;
796
+ }
797
+ await sleep(delayMs);
798
+ }
799
+ }
766
800
  }
767
801
 
768
802
  /**
@@ -146,6 +146,7 @@ export async function harnessStartSheetDataset(input: {
146
146
  rows: Array<Record<string, unknown>>;
147
147
  runId: string;
148
148
  userEmail?: string | null;
149
+ preloadedDbSessions?: PreloadedRuntimeDbSessionInput[] | null;
149
150
  }): Promise<{
150
151
  inserted: number;
151
152
  skipped: number;
@@ -170,6 +171,7 @@ export async function harnessPersistCompletedSheetRows(input: {
170
171
  outputFields: string[];
171
172
  runId: string;
172
173
  userEmail?: string | null;
174
+ preloadedDbSessions?: PreloadedRuntimeDbSessionInput[] | null;
173
175
  }): Promise<{ ok: true; rowsWritten: number; tableNamespace: string }> {
174
176
  return requireBinding().persistCompletedMapRows(input);
175
177
  }
@@ -1,2 +1,2 @@
1
- export const SDK_VERSION = "0.1.22";
1
+ export const SDK_VERSION = "0.1.24";
2
2
  export const SDK_API_CONTRACT = "2026-05-runs-v2";
@@ -7,6 +7,7 @@ import {
7
7
  export const EXECUTION_PLAN_DEFAULTS = {
8
8
  inlineRowsLimit: 1_000,
9
9
  largeMapChunkSize: 5_000,
10
+ complexMapChunkSize: 1_000,
10
11
  workflowSoftStepBudget: 20_000,
11
12
  workflowHardStepBudget: 25_000,
12
13
  ingestStepCount: 1,
@@ -183,6 +184,10 @@ function extractPlanMaps(
183
184
  (substep): substep is Extract<PlayStaticSubstep, { type: 'waterfall' }> =>
184
185
  substep.type === 'waterfall',
185
186
  );
187
+ const fallbackStepSuites = substeps.filter(
188
+ (substep): substep is Extract<PlayStaticSubstep, { type: 'step_suite' }> =>
189
+ substep.type === 'step_suite',
190
+ );
186
191
  return substeps
187
192
  .filter(
188
193
  (substep): substep is Extract<PlayStaticSubstep, { type: 'map' }> =>
@@ -200,13 +205,33 @@ function extractPlanMaps(
200
205
  waterfallId: waterfall.id ?? waterfall.field,
201
206
  stageIds: waterfall.steps?.map((step) => step.id) ?? [],
202
207
  }));
208
+ const stepSuites = fallbackStepSuites.filter((stepSuite) => {
209
+ if (!mapSubstep.waterfallIds?.length) return true;
210
+ return mapSubstep.waterfallIds.includes(stepSuite.field);
211
+ });
212
+ const stepSuiteStepsPerChunk = stepSuites.reduce(
213
+ (max, stepSuite) => Math.max(max, stepSuite.steps.length),
214
+ 0,
215
+ );
216
+ const waterfallStepsPerChunk = waterfallStages.reduce(
217
+ (max, waterfall) => Math.max(max, waterfall.stageIds.length),
218
+ 0,
219
+ );
220
+ const stepsPerChunk = Math.max(
221
+ 1,
222
+ waterfallStepsPerChunk,
223
+ stepSuiteStepsPerChunk,
224
+ );
203
225
  return {
204
226
  mapName: mapSubstep.name ?? mapSubstep.field,
205
227
  tableNamespace: mapSubstep.tableNamespace ?? mapSubstep.field,
206
228
  outputFields: mapSubstep.outputFields ?? [],
207
229
  waterfallStages,
208
- defaultChunkSize: EXECUTION_PLAN_DEFAULTS.largeMapChunkSize,
209
- stepsPerChunk: 1,
230
+ defaultChunkSize:
231
+ stepsPerChunk > 1
232
+ ? EXECUTION_PLAN_DEFAULTS.complexMapChunkSize
233
+ : EXECUTION_PLAN_DEFAULTS.largeMapChunkSize,
234
+ stepsPerChunk,
210
235
  };
211
236
  });
212
237
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "deepline",
3
- "version": "0.1.22",
3
+ "version": "0.1.24",
4
4
  "description": "Deepline SDK + CLI — B2B data enrichment powered by durable cloud execution",
5
5
  "license": "MIT",
6
6
  "repository": {