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.
- package/dist/cli/index.js +540 -56
- package/dist/cli/index.mjs +540 -56
- package/dist/index.d.mts +1 -1
- package/dist/index.d.ts +1 -1
- package/dist/index.js +30 -3
- package/dist/index.mjs +30 -3
- package/dist/repo/apps/play-runner-workers/src/coordinator-entry.ts +97 -81
- package/dist/repo/apps/play-runner-workers/src/dedup-do.ts +18 -5
- package/dist/repo/apps/play-runner-workers/src/entry.ts +43 -32
- package/dist/repo/apps/play-runner-workers/src/runtime/live-progress.ts +18 -0
- package/dist/repo/sdk/src/client.ts +38 -4
- package/dist/repo/sdk/src/plays/harness-stub.ts +2 -0
- package/dist/repo/sdk/src/version.ts +1 -1
- package/dist/repo/shared_libs/play-runtime/execution-plan.ts +27 -2
- package/package.json +1 -1
|
@@ -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) ||
|
|
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: {
|
|
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: {
|
|
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
|
-
|
|
4520
|
-
|
|
4521
|
-
|
|
4522
|
-
|
|
4523
|
-
|
|
4524
|
-
|
|
4525
|
-
|
|
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
|
|
763
|
-
|
|
764
|
-
|
|
765
|
-
|
|
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.
|
|
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:
|
|
209
|
-
|
|
230
|
+
defaultChunkSize:
|
|
231
|
+
stepsPerChunk > 1
|
|
232
|
+
? EXECUTION_PLAN_DEFAULTS.complexMapChunkSize
|
|
233
|
+
: EXECUTION_PLAN_DEFAULTS.largeMapChunkSize,
|
|
234
|
+
stepsPerChunk,
|
|
210
235
|
};
|
|
211
236
|
});
|
|
212
237
|
}
|