deepline 0.1.63 → 0.1.64
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 +702 -339
- package/dist/cli/index.mjs +727 -348
- package/dist/index.d.mts +1 -1
- package/dist/index.d.ts +1 -1
- package/dist/index.js +56 -40
- package/dist/index.mjs +56 -40
- package/dist/repo/apps/play-runner-workers/src/coordinator-entry.ts +9 -10
- package/dist/repo/apps/play-runner-workers/src/runtime/dataset-handles.ts +36 -27
- package/dist/repo/apps/play-runner-workers/src/runtime/tool-http-errors.ts +5 -2
- package/dist/repo/sdk/src/client.ts +71 -63
- package/dist/repo/sdk/src/errors.ts +5 -1
- package/dist/repo/sdk/src/http.ts +25 -17
- package/dist/repo/sdk/src/plays/local-file-discovery.ts +93 -24
- package/dist/repo/sdk/src/release.ts +2 -2
- package/dist/repo/sdk/src/tool-output.ts +40 -20
- package/dist/repo/shared_libs/play-runtime/batch-runtime.ts +10 -3
- package/dist/repo/shared_libs/play-runtime/batching-types.ts +15 -4
- package/dist/repo/shared_libs/play-runtime/coordinator-headers.ts +2 -1
- package/dist/repo/shared_libs/play-runtime/dedup-backend.ts +0 -0
- package/dist/repo/shared_libs/play-runtime/default-batch-strategies.ts +3 -4
- package/dist/repo/shared_libs/play-runtime/run-failure.ts +1 -3
- package/dist/repo/shared_libs/play-runtime/step-lifecycle-tracker.ts +4 -1
- package/dist/repo/shared_libs/play-runtime/tool-batch-executor.ts +4 -1
- package/dist/repo/shared_libs/plays/dataset.ts +10 -11
- package/package.json +1 -1
package/dist/index.d.mts
CHANGED
|
@@ -1206,7 +1206,7 @@ declare class DeeplineClient {
|
|
|
1206
1206
|
* artifactStorageKey: 'plays/v1/orgs/acme/plays/my-play/artifacts/playgraph_abc123.json',
|
|
1207
1207
|
* });
|
|
1208
1208
|
* ```
|
|
1209
|
-
|
|
1209
|
+
*/
|
|
1210
1210
|
startPlayRun(request: StartPlayRunRequest): Promise<PlayRunStart>;
|
|
1211
1211
|
startPlayRunStream(request: StartPlayRunRequest, options?: {
|
|
1212
1212
|
signal?: AbortSignal;
|
package/dist/index.d.ts
CHANGED
|
@@ -1206,7 +1206,7 @@ declare class DeeplineClient {
|
|
|
1206
1206
|
* artifactStorageKey: 'plays/v1/orgs/acme/plays/my-play/artifacts/playgraph_abc123.json',
|
|
1207
1207
|
* });
|
|
1208
1208
|
* ```
|
|
1209
|
-
|
|
1209
|
+
*/
|
|
1210
1210
|
startPlayRun(request: StartPlayRunRequest): Promise<PlayRunStart>;
|
|
1211
1211
|
startPlayRunStream(request: StartPlayRunRequest, options?: {
|
|
1212
1212
|
signal?: AbortSignal;
|
package/dist/index.js
CHANGED
|
@@ -88,7 +88,11 @@ var RateLimitError = class extends DeeplineError {
|
|
|
88
88
|
/** Milliseconds to wait before retrying, from the `Retry-After` response header. Defaults to 5000. */
|
|
89
89
|
retryAfterMs;
|
|
90
90
|
constructor(retryAfterMs = 5e3, message) {
|
|
91
|
-
super(
|
|
91
|
+
super(
|
|
92
|
+
message ?? `Rate limited. Retry after ${retryAfterMs}ms.`,
|
|
93
|
+
429,
|
|
94
|
+
"RATE_LIMIT"
|
|
95
|
+
);
|
|
92
96
|
this.name = "RateLimitError";
|
|
93
97
|
this.retryAfterMs = retryAfterMs;
|
|
94
98
|
}
|
|
@@ -232,10 +236,10 @@ function resolveConfig(options) {
|
|
|
232
236
|
|
|
233
237
|
// src/release.ts
|
|
234
238
|
var SDK_RELEASE = {
|
|
235
|
-
version: "0.1.
|
|
239
|
+
version: "0.1.64",
|
|
236
240
|
apiContract: "2026-05-play-bootstrap-dataset-summary",
|
|
237
241
|
supportPolicy: {
|
|
238
|
-
latest: "0.1.
|
|
242
|
+
latest: "0.1.64",
|
|
239
243
|
minimumSupported: "0.1.53",
|
|
240
244
|
deprecatedBelow: "0.1.53"
|
|
241
245
|
}
|
|
@@ -258,7 +262,7 @@ var HttpClient = class {
|
|
|
258
262
|
config;
|
|
259
263
|
authHeaders(extra) {
|
|
260
264
|
const headers = {
|
|
261
|
-
|
|
265
|
+
Authorization: `Bearer ${this.config.apiKey}`,
|
|
262
266
|
"User-Agent": `deepline-ts-sdk/${SDK_VERSION}`,
|
|
263
267
|
"X-Deepline-SDK-Version": SDK_VERSION,
|
|
264
268
|
"X-Deepline-API-Contract": SDK_API_CONTRACT,
|
|
@@ -941,31 +945,34 @@ var DeeplineClient = class {
|
|
|
941
945
|
* artifactStorageKey: 'plays/v1/orgs/acme/plays/my-play/artifacts/playgraph_abc123.json',
|
|
942
946
|
* });
|
|
943
947
|
* ```
|
|
944
|
-
|
|
948
|
+
*/
|
|
945
949
|
async startPlayRun(request) {
|
|
946
|
-
const response = await this.http.post(
|
|
947
|
-
|
|
948
|
-
|
|
949
|
-
|
|
950
|
-
|
|
951
|
-
|
|
952
|
-
|
|
953
|
-
|
|
954
|
-
|
|
955
|
-
|
|
956
|
-
|
|
957
|
-
|
|
958
|
-
|
|
959
|
-
|
|
960
|
-
|
|
961
|
-
|
|
962
|
-
|
|
963
|
-
|
|
964
|
-
|
|
965
|
-
|
|
966
|
-
|
|
967
|
-
|
|
968
|
-
|
|
950
|
+
const response = await this.http.post(
|
|
951
|
+
"/api/v2/plays/run",
|
|
952
|
+
{
|
|
953
|
+
...request.name ? { name: request.name } : {},
|
|
954
|
+
...request.revisionId ? { revisionId: request.revisionId } : {},
|
|
955
|
+
...request.artifactStorageKey ? { artifactStorageKey: request.artifactStorageKey } : {},
|
|
956
|
+
...request.sourceCode ? { sourceCode: request.sourceCode } : {},
|
|
957
|
+
...request.sourceFiles ? { sourceFiles: request.sourceFiles } : {},
|
|
958
|
+
..."staticPipeline" in request ? { staticPipeline: request.staticPipeline } : {},
|
|
959
|
+
...request.artifactHash ? { artifactHash: request.artifactHash } : {},
|
|
960
|
+
...request.graphHash ? { graphHash: request.graphHash } : {},
|
|
961
|
+
...request.runtimeArtifact ? { runtimeArtifact: request.runtimeArtifact } : {},
|
|
962
|
+
...request.compilerManifest ? { compilerManifest: request.compilerManifest } : {},
|
|
963
|
+
...request.inputFileUpload ? { inputFileUpload: request.inputFileUpload } : {},
|
|
964
|
+
...request.packagedFileUploads?.length ? { packagedFileUploads: request.packagedFileUploads } : {},
|
|
965
|
+
...request.input ? { input: request.input } : {},
|
|
966
|
+
...request.inputFile ? { inputFile: request.inputFile } : {},
|
|
967
|
+
...request.packagedFiles?.length ? { packagedFiles: request.packagedFiles } : {},
|
|
968
|
+
...request.force ? { force: true } : {},
|
|
969
|
+
...typeof request.waitForCompletionMs === "number" ? { waitForCompletionMs: request.waitForCompletionMs } : {},
|
|
970
|
+
// Profile selection is the API's job, not the CLI's. The server
|
|
971
|
+
// hardcodes workers_edge as the default; tests that want a
|
|
972
|
+
// different profile pass `request.profile` explicitly.
|
|
973
|
+
...request.profile ? { profile: request.profile } : {}
|
|
974
|
+
}
|
|
975
|
+
);
|
|
969
976
|
return normalizePlayRunStart(response);
|
|
970
977
|
}
|
|
971
978
|
async *startPlayRunStream(request, options) {
|
|
@@ -1217,10 +1224,7 @@ var DeeplineClient = class {
|
|
|
1217
1224
|
}
|
|
1218
1225
|
return formData;
|
|
1219
1226
|
};
|
|
1220
|
-
const response = await this.http.postFormData(
|
|
1221
|
-
"/api/v2/plays/files/stage",
|
|
1222
|
-
buildFormData
|
|
1223
|
-
);
|
|
1227
|
+
const response = await this.http.postFormData("/api/v2/plays/files/stage", buildFormData);
|
|
1224
1228
|
return response.files;
|
|
1225
1229
|
}
|
|
1226
1230
|
async resolveStagedPlayFiles(files) {
|
|
@@ -1667,7 +1671,9 @@ var DeeplineClient = class {
|
|
|
1667
1671
|
}
|
|
1668
1672
|
options?.onProgress?.(status);
|
|
1669
1673
|
if (TERMINAL_PLAY_STATUSES.has(status.status)) {
|
|
1670
|
-
const finalStatus = await this.getPlayStatus(
|
|
1674
|
+
const finalStatus = await this.getPlayStatus(
|
|
1675
|
+
status.runId || workflowId
|
|
1676
|
+
).catch(() => status);
|
|
1671
1677
|
return playRunResultFromStatus(finalStatus, start, workflowId);
|
|
1672
1678
|
}
|
|
1673
1679
|
}
|
|
@@ -2719,7 +2725,9 @@ function normalizeRows2(value) {
|
|
|
2719
2725
|
});
|
|
2720
2726
|
}
|
|
2721
2727
|
function candidateRoots(payload) {
|
|
2722
|
-
const roots = [
|
|
2728
|
+
const roots = [
|
|
2729
|
+
{ path: null, value: payload }
|
|
2730
|
+
];
|
|
2723
2731
|
if (isPlainObject(payload) && isPlainObject(payload.toolResponse)) {
|
|
2724
2732
|
roots.push({ path: "toolResponse", value: payload.toolResponse });
|
|
2725
2733
|
if (Object.prototype.hasOwnProperty.call(payload.toolResponse, "raw")) {
|
|
@@ -2746,7 +2754,9 @@ function candidateRoots(payload) {
|
|
|
2746
2754
|
function findBestArrayCandidate(value, pathPrefix = "", depth = 0) {
|
|
2747
2755
|
if (depth > 5) return null;
|
|
2748
2756
|
const directRows = normalizeRows2(value);
|
|
2749
|
-
const hasObjectRow = directRows?.some(
|
|
2757
|
+
const hasObjectRow = directRows?.some(
|
|
2758
|
+
(row) => Object.keys(row).some((key) => key !== "value")
|
|
2759
|
+
) ?? false;
|
|
2750
2760
|
let best = directRows && directRows.length > 0 && hasObjectRow ? { path: pathPrefix, rows: directRows } : null;
|
|
2751
2761
|
if (!isPlainObject(value)) {
|
|
2752
2762
|
return best;
|
|
@@ -2762,7 +2772,9 @@ function findBestArrayCandidate(value, pathPrefix = "", depth = 0) {
|
|
|
2762
2772
|
return best;
|
|
2763
2773
|
}
|
|
2764
2774
|
function tryConvertToList(payload, options) {
|
|
2765
|
-
const listExtractorPaths = Array.isArray(options?.listExtractorPaths) ? options?.listExtractorPaths.filter(
|
|
2775
|
+
const listExtractorPaths = Array.isArray(options?.listExtractorPaths) ? options?.listExtractorPaths.filter(
|
|
2776
|
+
(entry) => typeof entry === "string" && entry.trim().length > 0
|
|
2777
|
+
) : [];
|
|
2766
2778
|
if (listExtractorPaths.length > 0) {
|
|
2767
2779
|
for (const root of candidateRoots(payload)) {
|
|
2768
2780
|
for (const extractorPath of listExtractorPaths) {
|
|
@@ -2828,7 +2840,9 @@ function writeCsvOutputFile(rows, stem) {
|
|
|
2828
2840
|
const previewColumns = columns.slice(0, 5);
|
|
2829
2841
|
const preview = [
|
|
2830
2842
|
previewColumns.join(","),
|
|
2831
|
-
...previewRows.map(
|
|
2843
|
+
...previewRows.map(
|
|
2844
|
+
(row) => previewColumns.map((column) => escapeCell(row[column])).join(",")
|
|
2845
|
+
)
|
|
2832
2846
|
].join("\n");
|
|
2833
2847
|
return {
|
|
2834
2848
|
path: outputPath,
|
|
@@ -2841,9 +2855,11 @@ function extractSummaryFields(payload) {
|
|
|
2841
2855
|
const candidates = candidateRoots(payload);
|
|
2842
2856
|
for (const candidate of candidates) {
|
|
2843
2857
|
if (!isPlainObject(candidate.value)) continue;
|
|
2844
|
-
const summaryEntries = Object.entries(candidate.value).filter(
|
|
2845
|
-
|
|
2846
|
-
|
|
2858
|
+
const summaryEntries = Object.entries(candidate.value).filter(
|
|
2859
|
+
([, value]) => {
|
|
2860
|
+
return value == null || typeof value === "string" || typeof value === "number" || typeof value === "boolean";
|
|
2861
|
+
}
|
|
2862
|
+
);
|
|
2847
2863
|
if (summaryEntries.length === 0) continue;
|
|
2848
2864
|
return Object.fromEntries(summaryEntries);
|
|
2849
2865
|
}
|
package/dist/index.mjs
CHANGED
|
@@ -26,7 +26,11 @@ var RateLimitError = class extends DeeplineError {
|
|
|
26
26
|
/** Milliseconds to wait before retrying, from the `Retry-After` response header. Defaults to 5000. */
|
|
27
27
|
retryAfterMs;
|
|
28
28
|
constructor(retryAfterMs = 5e3, message) {
|
|
29
|
-
super(
|
|
29
|
+
super(
|
|
30
|
+
message ?? `Rate limited. Retry after ${retryAfterMs}ms.`,
|
|
31
|
+
429,
|
|
32
|
+
"RATE_LIMIT"
|
|
33
|
+
);
|
|
30
34
|
this.name = "RateLimitError";
|
|
31
35
|
this.retryAfterMs = retryAfterMs;
|
|
32
36
|
}
|
|
@@ -170,10 +174,10 @@ function resolveConfig(options) {
|
|
|
170
174
|
|
|
171
175
|
// src/release.ts
|
|
172
176
|
var SDK_RELEASE = {
|
|
173
|
-
version: "0.1.
|
|
177
|
+
version: "0.1.64",
|
|
174
178
|
apiContract: "2026-05-play-bootstrap-dataset-summary",
|
|
175
179
|
supportPolicy: {
|
|
176
|
-
latest: "0.1.
|
|
180
|
+
latest: "0.1.64",
|
|
177
181
|
minimumSupported: "0.1.53",
|
|
178
182
|
deprecatedBelow: "0.1.53"
|
|
179
183
|
}
|
|
@@ -196,7 +200,7 @@ var HttpClient = class {
|
|
|
196
200
|
config;
|
|
197
201
|
authHeaders(extra) {
|
|
198
202
|
const headers = {
|
|
199
|
-
|
|
203
|
+
Authorization: `Bearer ${this.config.apiKey}`,
|
|
200
204
|
"User-Agent": `deepline-ts-sdk/${SDK_VERSION}`,
|
|
201
205
|
"X-Deepline-SDK-Version": SDK_VERSION,
|
|
202
206
|
"X-Deepline-API-Contract": SDK_API_CONTRACT,
|
|
@@ -879,31 +883,34 @@ var DeeplineClient = class {
|
|
|
879
883
|
* artifactStorageKey: 'plays/v1/orgs/acme/plays/my-play/artifacts/playgraph_abc123.json',
|
|
880
884
|
* });
|
|
881
885
|
* ```
|
|
882
|
-
|
|
886
|
+
*/
|
|
883
887
|
async startPlayRun(request) {
|
|
884
|
-
const response = await this.http.post(
|
|
885
|
-
|
|
886
|
-
|
|
887
|
-
|
|
888
|
-
|
|
889
|
-
|
|
890
|
-
|
|
891
|
-
|
|
892
|
-
|
|
893
|
-
|
|
894
|
-
|
|
895
|
-
|
|
896
|
-
|
|
897
|
-
|
|
898
|
-
|
|
899
|
-
|
|
900
|
-
|
|
901
|
-
|
|
902
|
-
|
|
903
|
-
|
|
904
|
-
|
|
905
|
-
|
|
906
|
-
|
|
888
|
+
const response = await this.http.post(
|
|
889
|
+
"/api/v2/plays/run",
|
|
890
|
+
{
|
|
891
|
+
...request.name ? { name: request.name } : {},
|
|
892
|
+
...request.revisionId ? { revisionId: request.revisionId } : {},
|
|
893
|
+
...request.artifactStorageKey ? { artifactStorageKey: request.artifactStorageKey } : {},
|
|
894
|
+
...request.sourceCode ? { sourceCode: request.sourceCode } : {},
|
|
895
|
+
...request.sourceFiles ? { sourceFiles: request.sourceFiles } : {},
|
|
896
|
+
..."staticPipeline" in request ? { staticPipeline: request.staticPipeline } : {},
|
|
897
|
+
...request.artifactHash ? { artifactHash: request.artifactHash } : {},
|
|
898
|
+
...request.graphHash ? { graphHash: request.graphHash } : {},
|
|
899
|
+
...request.runtimeArtifact ? { runtimeArtifact: request.runtimeArtifact } : {},
|
|
900
|
+
...request.compilerManifest ? { compilerManifest: request.compilerManifest } : {},
|
|
901
|
+
...request.inputFileUpload ? { inputFileUpload: request.inputFileUpload } : {},
|
|
902
|
+
...request.packagedFileUploads?.length ? { packagedFileUploads: request.packagedFileUploads } : {},
|
|
903
|
+
...request.input ? { input: request.input } : {},
|
|
904
|
+
...request.inputFile ? { inputFile: request.inputFile } : {},
|
|
905
|
+
...request.packagedFiles?.length ? { packagedFiles: request.packagedFiles } : {},
|
|
906
|
+
...request.force ? { force: true } : {},
|
|
907
|
+
...typeof request.waitForCompletionMs === "number" ? { waitForCompletionMs: request.waitForCompletionMs } : {},
|
|
908
|
+
// Profile selection is the API's job, not the CLI's. The server
|
|
909
|
+
// hardcodes workers_edge as the default; tests that want a
|
|
910
|
+
// different profile pass `request.profile` explicitly.
|
|
911
|
+
...request.profile ? { profile: request.profile } : {}
|
|
912
|
+
}
|
|
913
|
+
);
|
|
907
914
|
return normalizePlayRunStart(response);
|
|
908
915
|
}
|
|
909
916
|
async *startPlayRunStream(request, options) {
|
|
@@ -1155,10 +1162,7 @@ var DeeplineClient = class {
|
|
|
1155
1162
|
}
|
|
1156
1163
|
return formData;
|
|
1157
1164
|
};
|
|
1158
|
-
const response = await this.http.postFormData(
|
|
1159
|
-
"/api/v2/plays/files/stage",
|
|
1160
|
-
buildFormData
|
|
1161
|
-
);
|
|
1165
|
+
const response = await this.http.postFormData("/api/v2/plays/files/stage", buildFormData);
|
|
1162
1166
|
return response.files;
|
|
1163
1167
|
}
|
|
1164
1168
|
async resolveStagedPlayFiles(files) {
|
|
@@ -1605,7 +1609,9 @@ var DeeplineClient = class {
|
|
|
1605
1609
|
}
|
|
1606
1610
|
options?.onProgress?.(status);
|
|
1607
1611
|
if (TERMINAL_PLAY_STATUSES.has(status.status)) {
|
|
1608
|
-
const finalStatus = await this.getPlayStatus(
|
|
1612
|
+
const finalStatus = await this.getPlayStatus(
|
|
1613
|
+
status.runId || workflowId
|
|
1614
|
+
).catch(() => status);
|
|
1609
1615
|
return playRunResultFromStatus(finalStatus, start, workflowId);
|
|
1610
1616
|
}
|
|
1611
1617
|
}
|
|
@@ -2657,7 +2663,9 @@ function normalizeRows2(value) {
|
|
|
2657
2663
|
});
|
|
2658
2664
|
}
|
|
2659
2665
|
function candidateRoots(payload) {
|
|
2660
|
-
const roots = [
|
|
2666
|
+
const roots = [
|
|
2667
|
+
{ path: null, value: payload }
|
|
2668
|
+
];
|
|
2661
2669
|
if (isPlainObject(payload) && isPlainObject(payload.toolResponse)) {
|
|
2662
2670
|
roots.push({ path: "toolResponse", value: payload.toolResponse });
|
|
2663
2671
|
if (Object.prototype.hasOwnProperty.call(payload.toolResponse, "raw")) {
|
|
@@ -2684,7 +2692,9 @@ function candidateRoots(payload) {
|
|
|
2684
2692
|
function findBestArrayCandidate(value, pathPrefix = "", depth = 0) {
|
|
2685
2693
|
if (depth > 5) return null;
|
|
2686
2694
|
const directRows = normalizeRows2(value);
|
|
2687
|
-
const hasObjectRow = directRows?.some(
|
|
2695
|
+
const hasObjectRow = directRows?.some(
|
|
2696
|
+
(row) => Object.keys(row).some((key) => key !== "value")
|
|
2697
|
+
) ?? false;
|
|
2688
2698
|
let best = directRows && directRows.length > 0 && hasObjectRow ? { path: pathPrefix, rows: directRows } : null;
|
|
2689
2699
|
if (!isPlainObject(value)) {
|
|
2690
2700
|
return best;
|
|
@@ -2700,7 +2710,9 @@ function findBestArrayCandidate(value, pathPrefix = "", depth = 0) {
|
|
|
2700
2710
|
return best;
|
|
2701
2711
|
}
|
|
2702
2712
|
function tryConvertToList(payload, options) {
|
|
2703
|
-
const listExtractorPaths = Array.isArray(options?.listExtractorPaths) ? options?.listExtractorPaths.filter(
|
|
2713
|
+
const listExtractorPaths = Array.isArray(options?.listExtractorPaths) ? options?.listExtractorPaths.filter(
|
|
2714
|
+
(entry) => typeof entry === "string" && entry.trim().length > 0
|
|
2715
|
+
) : [];
|
|
2704
2716
|
if (listExtractorPaths.length > 0) {
|
|
2705
2717
|
for (const root of candidateRoots(payload)) {
|
|
2706
2718
|
for (const extractorPath of listExtractorPaths) {
|
|
@@ -2766,7 +2778,9 @@ function writeCsvOutputFile(rows, stem) {
|
|
|
2766
2778
|
const previewColumns = columns.slice(0, 5);
|
|
2767
2779
|
const preview = [
|
|
2768
2780
|
previewColumns.join(","),
|
|
2769
|
-
...previewRows.map(
|
|
2781
|
+
...previewRows.map(
|
|
2782
|
+
(row) => previewColumns.map((column) => escapeCell(row[column])).join(",")
|
|
2783
|
+
)
|
|
2770
2784
|
].join("\n");
|
|
2771
2785
|
return {
|
|
2772
2786
|
path: outputPath,
|
|
@@ -2779,9 +2793,11 @@ function extractSummaryFields(payload) {
|
|
|
2779
2793
|
const candidates = candidateRoots(payload);
|
|
2780
2794
|
for (const candidate of candidates) {
|
|
2781
2795
|
if (!isPlainObject(candidate.value)) continue;
|
|
2782
|
-
const summaryEntries = Object.entries(candidate.value).filter(
|
|
2783
|
-
|
|
2784
|
-
|
|
2796
|
+
const summaryEntries = Object.entries(candidate.value).filter(
|
|
2797
|
+
([, value]) => {
|
|
2798
|
+
return value == null || typeof value === "string" || typeof value === "number" || typeof value === "boolean";
|
|
2799
|
+
}
|
|
2800
|
+
);
|
|
2785
2801
|
if (summaryEntries.length === 0) continue;
|
|
2786
2802
|
return Object.fromEntries(summaryEntries);
|
|
2787
2803
|
}
|
|
@@ -991,12 +991,13 @@ async function persistWorkflowRetryState(input: {
|
|
|
991
991
|
childPlayManifests: stripRetryChildManifestCode(
|
|
992
992
|
input.params.childPlayManifests,
|
|
993
993
|
),
|
|
994
|
-
packagedFiles:
|
|
995
|
-
|
|
996
|
-
|
|
997
|
-
|
|
998
|
-
|
|
999
|
-
|
|
994
|
+
packagedFiles:
|
|
995
|
+
input.params.packagedFiles?.map((file) => ({
|
|
996
|
+
playPath: file.playPath,
|
|
997
|
+
storageKey: file.storageKey,
|
|
998
|
+
contentType: file.contentType,
|
|
999
|
+
bytes: file.bytes,
|
|
1000
|
+
})) ?? null,
|
|
1000
1001
|
};
|
|
1001
1002
|
await callWorkflowPool<{ ok?: unknown }>(input.env, '/run-retry-state-put', {
|
|
1002
1003
|
method: 'POST',
|
|
@@ -1115,9 +1116,7 @@ async function restartWorkflowAfterPlatformReset(input: {
|
|
|
1115
1116
|
instanceId: retryInstance.id,
|
|
1116
1117
|
started: true,
|
|
1117
1118
|
});
|
|
1118
|
-
input.ctx?.waitUntil(
|
|
1119
|
-
input.oldInstance.terminate().catch(() => undefined),
|
|
1120
|
-
);
|
|
1119
|
+
input.ctx?.waitUntil(input.oldInstance.terminate().catch(() => undefined));
|
|
1121
1120
|
recordCoordinatorPerfTraceBuffered(input.env, input.ctx, {
|
|
1122
1121
|
runId: input.runId,
|
|
1123
1122
|
phase: 'coordinator.platform_deploy_retry',
|
|
@@ -3177,7 +3176,7 @@ async function handleWorkflowRoute(input: {
|
|
|
3177
3176
|
error: error instanceof Error ? error.message : String(error),
|
|
3178
3177
|
},
|
|
3179
3178
|
});
|
|
3180
|
-
|
|
3179
|
+
});
|
|
3181
3180
|
input.ctx?.waitUntil(prewarmPromise);
|
|
3182
3181
|
}
|
|
3183
3182
|
await persistWorkflowRetryState({
|
|
@@ -35,7 +35,10 @@ export type WorkerDatasetCapabilities = {
|
|
|
35
35
|
materialization: 'bounded' | 'in_memory';
|
|
36
36
|
};
|
|
37
37
|
|
|
38
|
-
const datasetChunkReaders = new WeakMap<
|
|
38
|
+
const datasetChunkReaders = new WeakMap<
|
|
39
|
+
object,
|
|
40
|
+
DatasetChunkReader<DatasetRow>
|
|
41
|
+
>();
|
|
39
42
|
const datasetCountHints = new WeakMap<object, number | null>();
|
|
40
43
|
const datasetCapabilities = new WeakMap<object, WorkerDatasetCapabilities>();
|
|
41
44
|
|
|
@@ -154,11 +157,7 @@ export function createPersistedDatasetHandle<T extends DatasetRow>(input: {
|
|
|
154
157
|
sourceLabel?: string | null;
|
|
155
158
|
workProgress?: PlayDatasetWorkProgressSummary;
|
|
156
159
|
readRows: (input: { limit: number; offset: number }) => Promise<readonly T[]>;
|
|
157
|
-
trace?: (
|
|
158
|
-
phase: string,
|
|
159
|
-
ms: number,
|
|
160
|
-
extra?: Record<string, unknown>,
|
|
161
|
-
) => void;
|
|
160
|
+
trace?: (phase: string, ms: number, extra?: Record<string, unknown>) => void;
|
|
162
161
|
nowMs: () => number;
|
|
163
162
|
}): WorkerDatasetHandle<T> {
|
|
164
163
|
const datasetKind = input.datasetKind ?? 'map';
|
|
@@ -202,7 +201,9 @@ export function createPersistedDatasetHandle<T extends DatasetRow>(input: {
|
|
|
202
201
|
return rows.map(internalDatasetRow);
|
|
203
202
|
}
|
|
204
203
|
|
|
205
|
-
async function* readChunks(
|
|
204
|
+
async function* readChunks(
|
|
205
|
+
chunkSize: number,
|
|
206
|
+
): AsyncGenerator<T[], void, void> {
|
|
206
207
|
const size = normalizedChunkSize(chunkSize);
|
|
207
208
|
let offset = 0;
|
|
208
209
|
while (offset < count) {
|
|
@@ -255,13 +256,18 @@ export function createPersistedDatasetHandle<T extends DatasetRow>(input: {
|
|
|
255
256
|
}) as AsyncIterable<T>,
|
|
256
257
|
},
|
|
257
258
|
});
|
|
258
|
-
return registerChunkReader(
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
259
|
+
return registerChunkReader(
|
|
260
|
+
dataset,
|
|
261
|
+
(chunkSize) => readChunks(chunkSize),
|
|
262
|
+
count,
|
|
263
|
+
{
|
|
264
|
+
storage: 'runtime_sheet',
|
|
265
|
+
chunkReadable: true,
|
|
266
|
+
pageBacked: true,
|
|
267
|
+
replayable: true,
|
|
268
|
+
materialization: 'bounded',
|
|
269
|
+
},
|
|
270
|
+
);
|
|
265
271
|
}
|
|
266
272
|
|
|
267
273
|
export function createCsvDatasetHandle<T extends DatasetRow>(input: {
|
|
@@ -274,17 +280,15 @@ export function createCsvDatasetHandle<T extends DatasetRow>(input: {
|
|
|
274
280
|
byteChunks: AsyncIterable<Uint8Array>,
|
|
275
281
|
chunkSize: number,
|
|
276
282
|
) => AsyncIterable<T[]>;
|
|
277
|
-
trace?: (
|
|
278
|
-
phase: string,
|
|
279
|
-
ms: number,
|
|
280
|
-
extra?: Record<string, unknown>,
|
|
281
|
-
) => void;
|
|
283
|
+
trace?: (phase: string, ms: number, extra?: Record<string, unknown>) => void;
|
|
282
284
|
nowMs: () => number;
|
|
283
285
|
}): WorkerDatasetHandle<T> {
|
|
284
286
|
const datasetId = `csv:${input.name}`;
|
|
285
287
|
let cachedCount: number | null = null;
|
|
286
288
|
|
|
287
|
-
async function* readChunks(
|
|
289
|
+
async function* readChunks(
|
|
290
|
+
chunkSize: number,
|
|
291
|
+
): AsyncGenerator<T[], void, void> {
|
|
288
292
|
const startedAt = input.nowMs();
|
|
289
293
|
let yieldedRows = 0;
|
|
290
294
|
let yieldedChunks = 0;
|
|
@@ -386,13 +390,18 @@ export function createCsvDatasetHandle<T extends DatasetRow>(input: {
|
|
|
386
390
|
}) as AsyncIterable<T>,
|
|
387
391
|
},
|
|
388
392
|
});
|
|
389
|
-
return registerChunkReader(
|
|
390
|
-
|
|
391
|
-
|
|
392
|
-
|
|
393
|
-
|
|
394
|
-
|
|
395
|
-
|
|
393
|
+
return registerChunkReader(
|
|
394
|
+
dataset,
|
|
395
|
+
(chunkSize) => readChunks(chunkSize),
|
|
396
|
+
null,
|
|
397
|
+
{
|
|
398
|
+
storage: 'csv_stream',
|
|
399
|
+
chunkReadable: true,
|
|
400
|
+
pageBacked: false,
|
|
401
|
+
replayable: true,
|
|
402
|
+
materialization: 'bounded',
|
|
403
|
+
},
|
|
404
|
+
);
|
|
396
405
|
}
|
|
397
406
|
|
|
398
407
|
export function createInlineDatasetHandle<T extends DatasetRow>(
|
|
@@ -79,7 +79,8 @@ function normalizeHardBillingPayload(
|
|
|
79
79
|
: 'MONTHLY_BILLING_LIMIT_EXCEEDED',
|
|
80
80
|
error_category: 'billing',
|
|
81
81
|
failure_origin:
|
|
82
|
-
typeof payload.failure_origin === 'string' &&
|
|
82
|
+
typeof payload.failure_origin === 'string' &&
|
|
83
|
+
payload.failure_origin.trim()
|
|
83
84
|
? payload.failure_origin
|
|
84
85
|
: 'deepline_billing',
|
|
85
86
|
message:
|
|
@@ -194,5 +195,7 @@ export function extractErrorBilling(
|
|
|
194
195
|
}
|
|
195
196
|
|
|
196
197
|
export function isHardBillingToolHttpError(error: unknown): boolean {
|
|
197
|
-
return
|
|
198
|
+
return (
|
|
199
|
+
error instanceof ToolHttpError && isHardBillingFailurePayload(error.billing)
|
|
200
|
+
);
|
|
198
201
|
}
|