deepline 0.2.55 → 0.2.56
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/bundling-sources/sdk/src/client.ts +14 -0
- package/dist/bundling-sources/sdk/src/http.ts +19 -1
- package/dist/bundling-sources/sdk/src/release.ts +1 -1
- package/dist/bundling-sources/sdk/src/stream-reconnect.ts +6 -0
- package/dist/bundling-sources/sdk/src/types.ts +7 -0
- package/dist/bundling-sources/shared_libs/play-runtime/app-runtime-api.ts +146 -12
- package/dist/bundling-sources/shared_libs/play-runtime/batch-runtime.ts +6 -3
- package/dist/bundling-sources/shared_libs/play-runtime/context.ts +1631 -748
- package/dist/bundling-sources/shared_libs/play-runtime/ctx-types.ts +20 -0
- package/dist/bundling-sources/shared_libs/play-runtime/durable-receipt-execution.ts +81 -52
- package/dist/bundling-sources/shared_libs/play-runtime/fixture-behavior.ts +146 -6
- package/dist/bundling-sources/shared_libs/play-runtime/gateway-auth-session.ts +56 -22
- package/dist/bundling-sources/shared_libs/play-runtime/governor/app-runtime-rate-state-backend.ts +14 -11
- package/dist/bundling-sources/shared_libs/play-runtime/governor/governor.ts +21 -2
- package/dist/bundling-sources/shared_libs/play-runtime/governor/policy.ts +81 -21
- package/dist/bundling-sources/shared_libs/play-runtime/output-size-limits.ts +7 -0
- package/dist/bundling-sources/shared_libs/play-runtime/protocol.ts +3 -0
- package/dist/bundling-sources/shared_libs/play-runtime/runner-backends/backends/daytona-lifecycle.ts +21 -0
- package/dist/bundling-sources/shared_libs/play-runtime/runner-backends/backends/daytona-payload-transport.ts +27 -2
- package/dist/bundling-sources/shared_libs/play-runtime/runner-backends/backends/daytona-runtime-watchdog.ts +49 -10
- package/dist/bundling-sources/shared_libs/play-runtime/runner-backends/backends/daytona.ts +96 -3
- package/dist/bundling-sources/shared_libs/play-runtime/runtime-api.ts +341 -67
- package/dist/bundling-sources/shared_libs/play-runtime/runtime-capacity-policy.ts +10 -0
- package/dist/bundling-sources/shared_libs/play-runtime/runtime-contract.ts +8 -1
- package/dist/bundling-sources/shared_libs/play-runtime/runtime-pg-driver-pg.ts +17 -2
- package/dist/bundling-sources/shared_libs/play-runtime/runtime-pg-driver.ts +4 -1
- package/dist/bundling-sources/shared_libs/play-runtime/runtime-receipt-store-adapter.ts +17 -1
- package/dist/bundling-sources/shared_libs/play-runtime/runtime-receipt-writer.ts +16 -2
- package/dist/bundling-sources/shared_libs/play-runtime/runtime-sheet-row-writer.ts +25 -0
- package/dist/bundling-sources/shared_libs/play-runtime/scheduler-backend.ts +3 -0
- package/dist/bundling-sources/shared_libs/play-runtime/suspension.ts +2 -0
- package/dist/bundling-sources/shared_libs/play-runtime/test-runtime-seams.ts +80 -1
- package/dist/bundling-sources/shared_libs/security/safe-fetch.ts +9 -0
- package/dist/bundling-sources/shared_libs/security/safe-outbound-fetch.ts +85 -48
- package/dist/cli/index.js +409 -51
- package/dist/cli/index.mjs +389 -25
- package/dist/index.d.mts +19 -1
- package/dist/index.d.ts +19 -1
- package/dist/index.js +29 -2
- package/dist/index.mjs +29 -2
- package/package.json +1 -1
package/dist/cli/index.mjs
CHANGED
|
@@ -1030,7 +1030,7 @@ var SDK_RELEASE = {
|
|
|
1030
1030
|
// 0.2.0 makes Dataset Handles uniformly async-only after 0.1.320 briefly
|
|
1031
1031
|
// exposed storage-dependent synchronous access. This deliberate minor
|
|
1032
1032
|
// release keeps lazy paging semantics independent of row residency.
|
|
1033
|
-
version: "0.2.
|
|
1033
|
+
version: "0.2.56",
|
|
1034
1034
|
contracts: {
|
|
1035
1035
|
api: {
|
|
1036
1036
|
name: "sdk-http-api",
|
|
@@ -1613,9 +1613,26 @@ var HttpClient = class {
|
|
|
1613
1613
|
if (error instanceof AuthError || error instanceof DeeplineError) {
|
|
1614
1614
|
throw error;
|
|
1615
1615
|
}
|
|
1616
|
-
|
|
1616
|
+
const normalized = error instanceof Error ? error : new Error(String(error));
|
|
1617
|
+
if (isAbortLikeError(normalized) && options?.signal?.aborted) {
|
|
1618
|
+
throw new DeeplineError(
|
|
1619
|
+
`Stream from ${this.config.baseUrl} was aborted by the caller.`,
|
|
1620
|
+
void 0,
|
|
1621
|
+
"ABORTED"
|
|
1622
|
+
);
|
|
1623
|
+
}
|
|
1624
|
+
lastError = normalized;
|
|
1617
1625
|
}
|
|
1618
1626
|
}
|
|
1627
|
+
if (lastError && isAbortLikeError(lastError)) {
|
|
1628
|
+
throw new DeeplineError(
|
|
1629
|
+
withCoworkNetworkHint(
|
|
1630
|
+
`Unable to stream from ${this.config.baseUrl}. The remote stream was interrupted.`
|
|
1631
|
+
),
|
|
1632
|
+
void 0,
|
|
1633
|
+
"PLAY_STREAM_NETWORK_ABORTED"
|
|
1634
|
+
);
|
|
1635
|
+
}
|
|
1619
1636
|
throw new DeeplineError(
|
|
1620
1637
|
withCoworkNetworkHint(
|
|
1621
1638
|
lastError?.message ? `Unable to stream from ${this.config.baseUrl}. ${lastError.message}` : `Unable to stream from ${this.config.baseUrl}.`
|
|
@@ -1878,6 +1895,9 @@ function streamReconnectDelayMs(attempt) {
|
|
|
1878
1895
|
return Math.max(1, Math.floor(Math.random() * (cappedExponentialMs + 1)));
|
|
1879
1896
|
}
|
|
1880
1897
|
function isTransientPlayStreamError(error) {
|
|
1898
|
+
if (error instanceof DeeplineError && error.code === "PLAY_STREAM_NETWORK_ABORTED") {
|
|
1899
|
+
return true;
|
|
1900
|
+
}
|
|
1881
1901
|
if (error instanceof DeeplineError && typeof error.statusCode === "number") {
|
|
1882
1902
|
return error.statusCode >= 500 && error.statusCode < 600;
|
|
1883
1903
|
}
|
|
@@ -2030,6 +2050,7 @@ var RUNTIME_RECEIPT_OUTPUT_MAX_BYTES = 10 * 1024 * 1024;
|
|
|
2030
2050
|
var RUNTIME_RECEIPT_COMPLETION_BUFFER_MAX_BYTES = 32 * 1024 * 1024;
|
|
2031
2051
|
var RUNNER_TERMINAL_PUSH_MAX_BODY_BYTES = 16 * 1024 * 1024;
|
|
2032
2052
|
var RUNTIME_RECEIPT_GATEWAY_BATCH_MAX_BYTES = 12 * 1024 * 1024;
|
|
2053
|
+
var RUNTIME_RECEIPT_WRITER_TARGET_BATCH_BYTES = 4 * 1024 * 1024;
|
|
2033
2054
|
var RUNNER_POST_TERMINAL_DIAGNOSTIC_MAX_BYTES = 64 * 1024;
|
|
2034
2055
|
|
|
2035
2056
|
// ../shared_libs/play-runtime/ledger-safe-payload.ts
|
|
@@ -4612,6 +4633,10 @@ var DeeplineClient = class {
|
|
|
4612
4633
|
...request.packagedFiles?.length ? { packagedFiles: request.packagedFiles } : {},
|
|
4613
4634
|
...request.force ? { force: true } : {},
|
|
4614
4635
|
...forceToolRefresh ? { forceToolRefresh: true } : {},
|
|
4636
|
+
...typeof request.maxConcurrentExternalCalls === "number" ? {
|
|
4637
|
+
maxConcurrentExternalCalls: request.maxConcurrentExternalCalls
|
|
4638
|
+
} : {},
|
|
4639
|
+
...typeof request.maxConcurrentRows === "number" ? { maxConcurrentRows: request.maxConcurrentRows } : {},
|
|
4615
4640
|
...typeof request.waitForCompletionMs === "number" ? { waitForCompletionMs: request.waitForCompletionMs } : {},
|
|
4616
4641
|
// Profile selection is the API's job, not the CLI's. The server
|
|
4617
4642
|
// defaults to absurd; callers normally omit this field.
|
|
@@ -4664,6 +4689,8 @@ var DeeplineClient = class {
|
|
|
4664
4689
|
...request.packagedFiles?.length ? { packagedFiles: request.packagedFiles } : {},
|
|
4665
4690
|
...request.force ? { force: true } : {},
|
|
4666
4691
|
...forceToolRefresh ? { forceToolRefresh: true } : {},
|
|
4692
|
+
...typeof request.maxConcurrentExternalCalls === "number" ? { maxConcurrentExternalCalls: request.maxConcurrentExternalCalls } : {},
|
|
4693
|
+
...typeof request.maxConcurrentRows === "number" ? { maxConcurrentRows: request.maxConcurrentRows } : {},
|
|
4667
4694
|
...typeof request.waitForCompletionMs === "number" ? { waitForCompletionMs: request.waitForCompletionMs } : {},
|
|
4668
4695
|
...request.profile ? { profile: request.profile } : {},
|
|
4669
4696
|
...integrationMode ? { integrationMode } : {},
|
|
@@ -8756,14 +8783,14 @@ function invoiceDateText(createdAt) {
|
|
|
8756
8783
|
}
|
|
8757
8784
|
function invoiceLine(entry, compact) {
|
|
8758
8785
|
const amount = invoiceAmountText(entry.amount_cents, entry.currency);
|
|
8759
|
-
const
|
|
8786
|
+
const link2 = entry.url ?? "(no link)";
|
|
8760
8787
|
if (compact) {
|
|
8761
8788
|
return [
|
|
8762
8789
|
entry.id,
|
|
8763
8790
|
invoiceDateText(entry.created_at),
|
|
8764
8791
|
amount,
|
|
8765
8792
|
entry.status,
|
|
8766
|
-
|
|
8793
|
+
link2
|
|
8767
8794
|
].join(" | ");
|
|
8768
8795
|
}
|
|
8769
8796
|
return [
|
|
@@ -8771,7 +8798,7 @@ function invoiceLine(entry, compact) {
|
|
|
8771
8798
|
entry.description,
|
|
8772
8799
|
amount,
|
|
8773
8800
|
entry.status,
|
|
8774
|
-
|
|
8801
|
+
link2
|
|
8775
8802
|
].join(" | ");
|
|
8776
8803
|
}
|
|
8777
8804
|
async function handleInvoices(options) {
|
|
@@ -10925,7 +10952,7 @@ Examples:
|
|
|
10925
10952
|
// src/cli/commands/enrich.ts
|
|
10926
10953
|
import {
|
|
10927
10954
|
copyFile,
|
|
10928
|
-
lstat,
|
|
10955
|
+
lstat as lstat2,
|
|
10929
10956
|
mkdir as mkdir4,
|
|
10930
10957
|
mkdtemp,
|
|
10931
10958
|
readFile as readFile3,
|
|
@@ -10940,7 +10967,7 @@ import { basename as basename4, dirname as dirname10, extname as extname3, join
|
|
|
10940
10967
|
import { Option } from "commander";
|
|
10941
10968
|
|
|
10942
10969
|
// src/cli/commands/play.ts
|
|
10943
|
-
import { createHash as createHash4 } from "crypto";
|
|
10970
|
+
import { createHash as createHash4, randomUUID as randomUUID3 } from "crypto";
|
|
10944
10971
|
import {
|
|
10945
10972
|
existsSync as existsSync9,
|
|
10946
10973
|
readFileSync as readFileSync8,
|
|
@@ -10949,6 +10976,13 @@ import {
|
|
|
10949
10976
|
statSync as statSync3,
|
|
10950
10977
|
writeFileSync as writeFileSync9
|
|
10951
10978
|
} from "fs";
|
|
10979
|
+
import {
|
|
10980
|
+
lstat,
|
|
10981
|
+
link,
|
|
10982
|
+
open,
|
|
10983
|
+
readFile as readFileAsync,
|
|
10984
|
+
unlink
|
|
10985
|
+
} from "fs/promises";
|
|
10952
10986
|
import { basename as basename3, dirname as dirname9, join as join10, resolve as resolve11 } from "path";
|
|
10953
10987
|
import { parse as parseCsvSync2 } from "csv-parse/sync";
|
|
10954
10988
|
|
|
@@ -17623,6 +17657,31 @@ ${hint}`;
|
|
|
17623
17657
|
});
|
|
17624
17658
|
}
|
|
17625
17659
|
|
|
17660
|
+
// ../shared_libs/play-runtime/governor/policy.ts
|
|
17661
|
+
var DEFAULT_MAX_CONCURRENT_EXTERNAL_CALLS = 64;
|
|
17662
|
+
var MAX_CONFIGURABLE_CONCURRENT_EXTERNAL_CALLS = 256;
|
|
17663
|
+
var MAX_CONFIGURABLE_CONCURRENT_ROWS = 1e3;
|
|
17664
|
+
function resolveMaxConcurrentExternalCalls(requested) {
|
|
17665
|
+
if (requested === void 0 || requested === null) {
|
|
17666
|
+
return DEFAULT_MAX_CONCURRENT_EXTERNAL_CALLS;
|
|
17667
|
+
}
|
|
17668
|
+
if (!Number.isSafeInteger(requested) || requested < 1 || requested > MAX_CONFIGURABLE_CONCURRENT_EXTERNAL_CALLS) {
|
|
17669
|
+
throw new Error(
|
|
17670
|
+
`maxConcurrentExternalCalls must be a whole number from 1 through ${MAX_CONFIGURABLE_CONCURRENT_EXTERNAL_CALLS}.`
|
|
17671
|
+
);
|
|
17672
|
+
}
|
|
17673
|
+
return requested;
|
|
17674
|
+
}
|
|
17675
|
+
function resolveMaxConcurrentRows(requested) {
|
|
17676
|
+
if (requested === void 0 || requested === null) return null;
|
|
17677
|
+
if (!Number.isSafeInteger(requested) || requested < 1 || requested > MAX_CONFIGURABLE_CONCURRENT_ROWS) {
|
|
17678
|
+
throw new Error(
|
|
17679
|
+
`maxConcurrentRows must be a whole number from 1 through ${MAX_CONFIGURABLE_CONCURRENT_ROWS}.`
|
|
17680
|
+
);
|
|
17681
|
+
}
|
|
17682
|
+
return requested;
|
|
17683
|
+
}
|
|
17684
|
+
|
|
17626
17685
|
// ../shared_libs/play-runtime/sandbox-runtime-limits.ts
|
|
17627
17686
|
var PLAY_SANDBOX_SIZE_LIMITS = {
|
|
17628
17687
|
standard: {
|
|
@@ -17847,6 +17906,7 @@ function stripLeadingTimestamp(line) {
|
|
|
17847
17906
|
// ../shared_libs/play-runtime/fixture-behavior.ts
|
|
17848
17907
|
var FIXTURE_BEHAVIOR_VERSION = 1;
|
|
17849
17908
|
var FIXTURE_BEHAVIOR_RESPONSE_VERSION = 2;
|
|
17909
|
+
var FIXTURE_BEHAVIOR_REPLAY_VERSION = 3;
|
|
17850
17910
|
var MAX_FIXTURE_RESPONSE_DELAY_SAMPLES = 256;
|
|
17851
17911
|
var MAX_FIXTURE_RESPONSE_DELAY_MS = 8 * 6e4;
|
|
17852
17912
|
var MAX_FIXTURE_RESPONSE_ERROR_MESSAGE_LENGTH = 500;
|
|
@@ -17858,7 +17918,11 @@ function validateFixtureBehavior(value) {
|
|
|
17858
17918
|
return { ok: false, error: "fixtureBehavior must be a JSON object." };
|
|
17859
17919
|
}
|
|
17860
17920
|
const record = value;
|
|
17861
|
-
const supportedKeys = record.version === FIXTURE_BEHAVIOR_RESPONSE_VERSION
|
|
17921
|
+
const supportedKeys = record.version === FIXTURE_BEHAVIOR_RESPONSE_VERSION || record.version === FIXTURE_BEHAVIOR_REPLAY_VERSION ? /* @__PURE__ */ new Set([
|
|
17922
|
+
"version",
|
|
17923
|
+
"responseSamples",
|
|
17924
|
+
...record.version === FIXTURE_BEHAVIOR_REPLAY_VERSION ? ["replayBundle"] : []
|
|
17925
|
+
]) : /* @__PURE__ */ new Set(["version", "responseDelaySamplesMs"]);
|
|
17862
17926
|
const unknownKeys = Object.keys(record).filter(
|
|
17863
17927
|
(key) => !supportedKeys.has(key)
|
|
17864
17928
|
);
|
|
@@ -17868,13 +17932,13 @@ function validateFixtureBehavior(value) {
|
|
|
17868
17932
|
error: `Unsupported fixtureBehavior field "${unknownKeys[0]}".`
|
|
17869
17933
|
};
|
|
17870
17934
|
}
|
|
17871
|
-
if (record.version !== FIXTURE_BEHAVIOR_VERSION && record.version !== FIXTURE_BEHAVIOR_RESPONSE_VERSION) {
|
|
17935
|
+
if (record.version !== FIXTURE_BEHAVIOR_VERSION && record.version !== FIXTURE_BEHAVIOR_RESPONSE_VERSION && record.version !== FIXTURE_BEHAVIOR_REPLAY_VERSION) {
|
|
17872
17936
|
return {
|
|
17873
17937
|
ok: false,
|
|
17874
|
-
error: `fixtureBehavior.version must be ${FIXTURE_BEHAVIOR_VERSION} or ${FIXTURE_BEHAVIOR_RESPONSE_VERSION}.`
|
|
17938
|
+
error: `fixtureBehavior.version must be ${FIXTURE_BEHAVIOR_VERSION} or ${FIXTURE_BEHAVIOR_RESPONSE_VERSION}, or ${FIXTURE_BEHAVIOR_REPLAY_VERSION}.`
|
|
17875
17939
|
};
|
|
17876
17940
|
}
|
|
17877
|
-
if (record.version === FIXTURE_BEHAVIOR_RESPONSE_VERSION) {
|
|
17941
|
+
if (record.version === FIXTURE_BEHAVIOR_RESPONSE_VERSION || record.version === FIXTURE_BEHAVIOR_REPLAY_VERSION) {
|
|
17878
17942
|
if (!Array.isArray(record.responseSamples) || record.responseSamples.length === 0 || record.responseSamples.length > MAX_FIXTURE_RESPONSE_DELAY_SAMPLES) {
|
|
17879
17943
|
return {
|
|
17880
17944
|
ok: false,
|
|
@@ -17981,6 +18045,72 @@ function validateFixtureBehavior(value) {
|
|
|
17981
18045
|
...httpError ? { httpError } : {}
|
|
17982
18046
|
});
|
|
17983
18047
|
}
|
|
18048
|
+
let replayBundle;
|
|
18049
|
+
if (record.version === FIXTURE_BEHAVIOR_REPLAY_VERSION) {
|
|
18050
|
+
if (!record.replayBundle || typeof record.replayBundle !== "object" || Array.isArray(record.replayBundle)) {
|
|
18051
|
+
return {
|
|
18052
|
+
ok: false,
|
|
18053
|
+
error: "fixtureBehavior.replayBundle must be an object."
|
|
18054
|
+
};
|
|
18055
|
+
}
|
|
18056
|
+
const replay = record.replayBundle;
|
|
18057
|
+
const replayUnknownKeys = Object.keys(replay).filter(
|
|
18058
|
+
(key) => key !== "bundleId" && key !== "manifestSha256" && key !== "syntheticFallbackToolIds"
|
|
18059
|
+
);
|
|
18060
|
+
if (replayUnknownKeys.length > 0) {
|
|
18061
|
+
return {
|
|
18062
|
+
ok: false,
|
|
18063
|
+
error: `Unsupported fixtureBehavior.replayBundle field "${replayUnknownKeys[0]}".`
|
|
18064
|
+
};
|
|
18065
|
+
}
|
|
18066
|
+
const digestPattern = /^[a-f0-9]{64}$/;
|
|
18067
|
+
if (typeof replay.bundleId !== "string" || !digestPattern.test(replay.bundleId)) {
|
|
18068
|
+
return {
|
|
18069
|
+
ok: false,
|
|
18070
|
+
error: "fixtureBehavior.replayBundle.bundleId must be a lowercase SHA-256 digest."
|
|
18071
|
+
};
|
|
18072
|
+
}
|
|
18073
|
+
if (typeof replay.manifestSha256 !== "string" || !digestPattern.test(replay.manifestSha256)) {
|
|
18074
|
+
return {
|
|
18075
|
+
ok: false,
|
|
18076
|
+
error: "fixtureBehavior.replayBundle.manifestSha256 must be a lowercase SHA-256 digest."
|
|
18077
|
+
};
|
|
18078
|
+
}
|
|
18079
|
+
let syntheticFallbackToolIds;
|
|
18080
|
+
if (replay.syntheticFallbackToolIds !== void 0) {
|
|
18081
|
+
if (!Array.isArray(replay.syntheticFallbackToolIds) || replay.syntheticFallbackToolIds.length === 0 || replay.syntheticFallbackToolIds.length > 32) {
|
|
18082
|
+
return {
|
|
18083
|
+
ok: false,
|
|
18084
|
+
error: "fixtureBehavior.replayBundle.syntheticFallbackToolIds must contain 1-32 tool ids."
|
|
18085
|
+
};
|
|
18086
|
+
}
|
|
18087
|
+
syntheticFallbackToolIds = [];
|
|
18088
|
+
for (const rawToolId of replay.syntheticFallbackToolIds) {
|
|
18089
|
+
if (typeof rawToolId !== "string" || rawToolId !== rawToolId.trim().toLowerCase() || !/^[a-z0-9][a-z0-9_.-]*$/.test(rawToolId) || rawToolId.length > 250 || syntheticFallbackToolIds.includes(rawToolId)) {
|
|
18090
|
+
return {
|
|
18091
|
+
ok: false,
|
|
18092
|
+
error: "fixtureBehavior.replayBundle.syntheticFallbackToolIds contains an invalid tool id."
|
|
18093
|
+
};
|
|
18094
|
+
}
|
|
18095
|
+
syntheticFallbackToolIds.push(rawToolId);
|
|
18096
|
+
}
|
|
18097
|
+
}
|
|
18098
|
+
replayBundle = {
|
|
18099
|
+
bundleId: replay.bundleId,
|
|
18100
|
+
manifestSha256: replay.manifestSha256,
|
|
18101
|
+
...syntheticFallbackToolIds ? { syntheticFallbackToolIds } : {}
|
|
18102
|
+
};
|
|
18103
|
+
}
|
|
18104
|
+
if (record.version === FIXTURE_BEHAVIOR_REPLAY_VERSION) {
|
|
18105
|
+
return {
|
|
18106
|
+
ok: true,
|
|
18107
|
+
behavior: {
|
|
18108
|
+
version: FIXTURE_BEHAVIOR_REPLAY_VERSION,
|
|
18109
|
+
responseSamples: samples2,
|
|
18110
|
+
replayBundle
|
|
18111
|
+
}
|
|
18112
|
+
};
|
|
18113
|
+
}
|
|
17984
18114
|
return {
|
|
17985
18115
|
ok: true,
|
|
17986
18116
|
behavior: {
|
|
@@ -18073,6 +18203,114 @@ var PLAY_RUN_RESERVED_BOOLEAN_FLAGS = /* @__PURE__ */ new Set([
|
|
|
18073
18203
|
"--debug-map-latency",
|
|
18074
18204
|
"--debug-fixture-provider-pacing"
|
|
18075
18205
|
]);
|
|
18206
|
+
async function pathExistsIncludingSymlink(path) {
|
|
18207
|
+
try {
|
|
18208
|
+
await lstat(path);
|
|
18209
|
+
return true;
|
|
18210
|
+
} catch (error) {
|
|
18211
|
+
if (error.code === "ENOENT") {
|
|
18212
|
+
return false;
|
|
18213
|
+
}
|
|
18214
|
+
throw error;
|
|
18215
|
+
}
|
|
18216
|
+
}
|
|
18217
|
+
function runIdFileTempPath(destination) {
|
|
18218
|
+
return join10(
|
|
18219
|
+
dirname9(destination),
|
|
18220
|
+
`.${basename3(destination)}.${process.pid}.${randomUUID3()}.tmp`
|
|
18221
|
+
);
|
|
18222
|
+
}
|
|
18223
|
+
async function removeRunIdTempFile(path) {
|
|
18224
|
+
try {
|
|
18225
|
+
await unlink(path);
|
|
18226
|
+
} catch (error) {
|
|
18227
|
+
if (error.code !== "ENOENT") {
|
|
18228
|
+
throw error;
|
|
18229
|
+
}
|
|
18230
|
+
}
|
|
18231
|
+
}
|
|
18232
|
+
async function preflightRunIdFile(path) {
|
|
18233
|
+
const destination = resolve11(path);
|
|
18234
|
+
if (await pathExistsIncludingSymlink(destination)) {
|
|
18235
|
+
throw new Error(
|
|
18236
|
+
`--run-id-file destination already exists: ${destination}. Choose a new path so this run cannot overwrite another run identity.`
|
|
18237
|
+
);
|
|
18238
|
+
}
|
|
18239
|
+
const tempPath = runIdFileTempPath(destination);
|
|
18240
|
+
let handle = null;
|
|
18241
|
+
try {
|
|
18242
|
+
handle = await open(tempPath, "wx", 384);
|
|
18243
|
+
await handle.sync();
|
|
18244
|
+
} catch (error) {
|
|
18245
|
+
throw new Error(
|
|
18246
|
+
`Cannot write --run-id-file destination ${destination}: ${error instanceof Error ? error.message : String(error)}`
|
|
18247
|
+
);
|
|
18248
|
+
} finally {
|
|
18249
|
+
await handle?.close();
|
|
18250
|
+
await removeRunIdTempFile(tempPath);
|
|
18251
|
+
}
|
|
18252
|
+
return destination;
|
|
18253
|
+
}
|
|
18254
|
+
async function readRunIdFile(destination) {
|
|
18255
|
+
if (!await pathExistsIncludingSymlink(destination)) {
|
|
18256
|
+
return null;
|
|
18257
|
+
}
|
|
18258
|
+
let parsed;
|
|
18259
|
+
try {
|
|
18260
|
+
parsed = JSON.parse(await readFileAsync(destination, "utf8"));
|
|
18261
|
+
} catch (error) {
|
|
18262
|
+
throw new Error(
|
|
18263
|
+
`--run-id-file destination contains invalid JSON: ${destination}. Refusing to overwrite it (${error instanceof Error ? error.message : String(error)}).`
|
|
18264
|
+
);
|
|
18265
|
+
}
|
|
18266
|
+
if (!parsed || typeof parsed !== "object" || parsed.version !== 1 || typeof parsed.runId !== "string" || !parsed.runId) {
|
|
18267
|
+
throw new Error(
|
|
18268
|
+
`--run-id-file destination has an unsupported identity record: ${destination}. Refusing to overwrite it.`
|
|
18269
|
+
);
|
|
18270
|
+
}
|
|
18271
|
+
return parsed;
|
|
18272
|
+
}
|
|
18273
|
+
async function writePlayRunIdFile(destination, runId) {
|
|
18274
|
+
const existing = await readRunIdFile(destination);
|
|
18275
|
+
if (existing) {
|
|
18276
|
+
if (existing.runId === runId) return;
|
|
18277
|
+
throw new Error(
|
|
18278
|
+
`--run-id-file destination already records run ${existing.runId}; refusing to replace it with ${runId}: ${destination}`
|
|
18279
|
+
);
|
|
18280
|
+
}
|
|
18281
|
+
const tempPath = runIdFileTempPath(destination);
|
|
18282
|
+
let handle = null;
|
|
18283
|
+
try {
|
|
18284
|
+
handle = await open(tempPath, "wx", 384);
|
|
18285
|
+
await handle.writeFile(
|
|
18286
|
+
`${JSON.stringify({ version: 1, runId })}
|
|
18287
|
+
`,
|
|
18288
|
+
"utf8"
|
|
18289
|
+
);
|
|
18290
|
+
await handle.sync();
|
|
18291
|
+
await handle.close();
|
|
18292
|
+
handle = null;
|
|
18293
|
+
try {
|
|
18294
|
+
await link(tempPath, destination);
|
|
18295
|
+
const directory = await open(dirname9(destination), "r");
|
|
18296
|
+
try {
|
|
18297
|
+
await directory.sync();
|
|
18298
|
+
} finally {
|
|
18299
|
+
await directory.close();
|
|
18300
|
+
}
|
|
18301
|
+
} catch (error) {
|
|
18302
|
+
if (error.code !== "EEXIST") throw error;
|
|
18303
|
+
const raced = await readRunIdFile(destination);
|
|
18304
|
+
if (raced?.runId === runId) return;
|
|
18305
|
+
throw new Error(
|
|
18306
|
+
`--run-id-file destination already records run ${raced?.runId ?? "<invalid>"}; refusing to replace it with ${runId}: ${destination}`
|
|
18307
|
+
);
|
|
18308
|
+
}
|
|
18309
|
+
} finally {
|
|
18310
|
+
await handle?.close();
|
|
18311
|
+
await removeRunIdTempFile(tempPath);
|
|
18312
|
+
}
|
|
18313
|
+
}
|
|
18076
18314
|
function traceCliSync(phase, fields, run) {
|
|
18077
18315
|
const startedAt = Date.now();
|
|
18078
18316
|
try {
|
|
@@ -19477,8 +19715,8 @@ function buildPlayDashboardUrl(baseUrl, playName) {
|
|
|
19477
19715
|
const encodedPlayName = encodeURIComponent(playName);
|
|
19478
19716
|
return `${trimmedBase}/dashboard/plays/${encodedPlayName}`;
|
|
19479
19717
|
}
|
|
19480
|
-
function openPlayDashboard(dashboardUrl,
|
|
19481
|
-
if (
|
|
19718
|
+
function openPlayDashboard(dashboardUrl, open2) {
|
|
19719
|
+
if (open2 && dashboardUrl) {
|
|
19482
19720
|
openInBrowser(dashboardUrl);
|
|
19483
19721
|
}
|
|
19484
19722
|
}
|
|
@@ -19514,9 +19752,11 @@ function assertPlayWaitNotTimedOut(input2) {
|
|
|
19514
19752
|
);
|
|
19515
19753
|
}
|
|
19516
19754
|
}
|
|
19755
|
+
var PLAY_DURABLE_STATUS_PROBE_INTERVAL_MS = 15e3;
|
|
19517
19756
|
async function waitForPlayCompletionByStream(input2) {
|
|
19518
19757
|
let lastPhase = null;
|
|
19519
19758
|
let reconnectAttempt = 0;
|
|
19759
|
+
let nextDurableProbeAt = Date.now() + PLAY_DURABLE_STATUS_PROBE_INTERVAL_MS;
|
|
19520
19760
|
const withDashboardUrl = (status) => input2.dashboardUrl ? { ...status, dashboardUrl: input2.dashboardUrl } : status;
|
|
19521
19761
|
const remainingWaitMs = () => input2.waitTimeoutMs === null ? null : input2.waitTimeoutMs - (Date.now() - input2.startedAt);
|
|
19522
19762
|
const fetchTerminalStatus = async () => {
|
|
@@ -19535,6 +19775,14 @@ async function waitForPlayCompletionByStream(input2) {
|
|
|
19535
19775
|
};
|
|
19536
19776
|
const handleLiveEvent = async (event) => {
|
|
19537
19777
|
assertPlayWaitNotTimedOut({ ...input2, lastPhase });
|
|
19778
|
+
const now = Date.now();
|
|
19779
|
+
if (now >= nextDurableProbeAt) {
|
|
19780
|
+
nextDurableProbeAt = now + PLAY_DURABLE_STATUS_PROBE_INTERVAL_MS;
|
|
19781
|
+
const durableTerminal = await fetchTerminalStatus();
|
|
19782
|
+
if (durableTerminal) {
|
|
19783
|
+
return durableTerminal;
|
|
19784
|
+
}
|
|
19785
|
+
}
|
|
19538
19786
|
const phase = describeLiveEventPhase(event);
|
|
19539
19787
|
if (phase) {
|
|
19540
19788
|
lastPhase = phase;
|
|
@@ -19783,7 +20031,7 @@ async function startAndWaitForPlayCompletionByStreamOnce(input2) {
|
|
|
19783
20031
|
lastKnownWorkflowId = eventRunId;
|
|
19784
20032
|
firstRunIdMs ??= Date.now() - startedAt;
|
|
19785
20033
|
if (runStartedNow) {
|
|
19786
|
-
input2.onRunStarted?.(eventRunId);
|
|
20034
|
+
await input2.onRunStarted?.(eventRunId);
|
|
19787
20035
|
}
|
|
19788
20036
|
}
|
|
19789
20037
|
if (eventConfirmsPlayRunLaunch(event) && eventRunId === lastKnownWorkflowId) {
|
|
@@ -21062,6 +21310,15 @@ function buildOrdinaryPlayRunCommand(options, resolvedRevisionId) {
|
|
|
21062
21310
|
}
|
|
21063
21311
|
if (options.profile)
|
|
21064
21312
|
parts.push("--profile", shellSingleQuote(options.profile));
|
|
21313
|
+
if (options.maxConcurrentExternalCalls !== null) {
|
|
21314
|
+
parts.push(
|
|
21315
|
+
"--max-concurrent-external-calls",
|
|
21316
|
+
String(options.maxConcurrentExternalCalls)
|
|
21317
|
+
);
|
|
21318
|
+
}
|
|
21319
|
+
if (options.maxConcurrentRows !== null) {
|
|
21320
|
+
parts.push("--max-concurrent-rows", String(options.maxConcurrentRows));
|
|
21321
|
+
}
|
|
21065
21322
|
const pinnedRevisionId = options.target.kind === "name" ? resolvedRevisionId ?? options.revisionId : null;
|
|
21066
21323
|
if (pinnedRevisionId) {
|
|
21067
21324
|
parts.push("--revision-id", shellSingleQuote(pinnedRevisionId));
|
|
@@ -21931,7 +22188,7 @@ function writeStartedPlayRun(input2) {
|
|
|
21931
22188
|
);
|
|
21932
22189
|
}
|
|
21933
22190
|
function parsePlayRunOptions(args) {
|
|
21934
|
-
const usage = "Usage: deepline plays run <play-name> [--input '{...}'] [--no-wait] [--tail-timeout-ms 30000] [--force] [--open] [--full] [--<input> value]\n deepline plays run <play-file.ts> [--input '{...}'] [--no-wait] [--tail-timeout-ms 30000] [--force] [--open] [--full] [--<input> value]\n deepline plays run --file <play-file.ts> [--input '{...}'] [--profile <id>] [--no-wait] [--tail-timeout-ms 30000] [--force] [--open] [--full] [--<input> value]\n deepline plays run --name <name> [--input '{...}'] [--profile <id>] [--live|--latest|--revision-id <id>] [--no-wait] [--tail-timeout-ms 30000] [--force] [--open] [--json] [--full] [--<input> value]\n Runs use the Absurd CJS runtime.\n Unknown --<input> value flags, such as --limit 5, are passed into play input.\nRun `deepline plays run --help` for idempotent call caching and ctx.dataset guidance.";
|
|
22191
|
+
const usage = "Usage: deepline plays run <play-name> [--input '{...}'] [--run-id-file <path>] [--no-wait] [--tail-timeout-ms 30000] [--force] [--open] [--full] [--<input> value]\n deepline plays run <play-file.ts> [--input '{...}'] [--run-id-file <path>] [--no-wait] [--tail-timeout-ms 30000] [--force] [--open] [--full] [--<input> value]\n deepline plays run --file <play-file.ts> [--input '{...}'] [--profile <id>] [--run-id-file <path>] [--no-wait] [--tail-timeout-ms 30000] [--force] [--open] [--full] [--<input> value]\n deepline plays run --name <name> [--input '{...}'] [--profile <id>] [--live|--latest|--revision-id <id>] [--run-id-file <path>] [--no-wait] [--tail-timeout-ms 30000] [--force] [--open] [--json] [--full] [--<input> value]\n Runs use the Absurd CJS runtime.\n Unknown --<input> value flags, such as --limit 5, are passed into play input.\nRun `deepline plays run --help` for idempotent call caching and ctx.dataset guidance.";
|
|
21935
22192
|
let filePath = null;
|
|
21936
22193
|
let playName = null;
|
|
21937
22194
|
let input2 = null;
|
|
@@ -21942,15 +22199,18 @@ function parsePlayRunOptions(args) {
|
|
|
21942
22199
|
const fullJson = args.includes("--full");
|
|
21943
22200
|
const emitLogs = !jsonOutput || args.includes("--logs");
|
|
21944
22201
|
const force = args.includes("--force");
|
|
21945
|
-
const
|
|
22202
|
+
const open2 = args.includes("--open");
|
|
21946
22203
|
const debugMapLatency = args.includes("--debug-map-latency");
|
|
21947
22204
|
const debugFixtureProviderPacing = args.includes(
|
|
21948
22205
|
"--debug-fixture-provider-pacing"
|
|
21949
22206
|
);
|
|
21950
22207
|
const verboseLogs = args.includes("--logs") || debugMapLatency;
|
|
21951
22208
|
let waitTimeoutMs = null;
|
|
22209
|
+
let maxConcurrentExternalCalls = null;
|
|
22210
|
+
let maxConcurrentRows = null;
|
|
21952
22211
|
let profile = null;
|
|
21953
22212
|
let fixtureBehavior = null;
|
|
22213
|
+
let runIdFile = null;
|
|
21954
22214
|
for (let index = 0; index < args.length; index += 1) {
|
|
21955
22215
|
const arg = args[index];
|
|
21956
22216
|
if (arg === "--file" && args[index + 1]) {
|
|
@@ -21965,6 +22225,23 @@ function parsePlayRunOptions(args) {
|
|
|
21965
22225
|
input2 = parseJsonInput(args[++index]);
|
|
21966
22226
|
continue;
|
|
21967
22227
|
}
|
|
22228
|
+
if (arg === "--run-id-file") {
|
|
22229
|
+
const value = args[index + 1];
|
|
22230
|
+
if (!value || value.startsWith("--")) {
|
|
22231
|
+
throw new Error("--run-id-file requires a destination path.");
|
|
22232
|
+
}
|
|
22233
|
+
runIdFile = value;
|
|
22234
|
+
index += 1;
|
|
22235
|
+
continue;
|
|
22236
|
+
}
|
|
22237
|
+
if (arg.startsWith("--run-id-file=")) {
|
|
22238
|
+
const value = arg.slice("--run-id-file=".length);
|
|
22239
|
+
if (!value) {
|
|
22240
|
+
throw new Error("--run-id-file requires a destination path.");
|
|
22241
|
+
}
|
|
22242
|
+
runIdFile = value;
|
|
22243
|
+
continue;
|
|
22244
|
+
}
|
|
21968
22245
|
if (arg === "--revision-id" && args[index + 1]) {
|
|
21969
22246
|
revisionId = args[++index];
|
|
21970
22247
|
continue;
|
|
@@ -21979,6 +22256,41 @@ function parsePlayRunOptions(args) {
|
|
|
21979
22256
|
index += 1;
|
|
21980
22257
|
continue;
|
|
21981
22258
|
}
|
|
22259
|
+
if (arg === "--max-concurrent-external-calls") {
|
|
22260
|
+
const value = args[index + 1];
|
|
22261
|
+
if (!value || value.startsWith("--")) {
|
|
22262
|
+
throw new Error(
|
|
22263
|
+
"--max-concurrent-external-calls requires a whole number."
|
|
22264
|
+
);
|
|
22265
|
+
}
|
|
22266
|
+
if (!/^[1-9]\d*$/.test(value)) {
|
|
22267
|
+
throw new Error(
|
|
22268
|
+
"--max-concurrent-external-calls requires a positive whole number."
|
|
22269
|
+
);
|
|
22270
|
+
}
|
|
22271
|
+
maxConcurrentExternalCalls = parsePositiveInteger3(
|
|
22272
|
+
value,
|
|
22273
|
+
"--max-concurrent-external-calls"
|
|
22274
|
+
);
|
|
22275
|
+
resolveMaxConcurrentExternalCalls(maxConcurrentExternalCalls);
|
|
22276
|
+
index += 1;
|
|
22277
|
+
continue;
|
|
22278
|
+
}
|
|
22279
|
+
if (arg === "--max-concurrent-rows") {
|
|
22280
|
+
const value = args[index + 1];
|
|
22281
|
+
if (!value || value.startsWith("--")) {
|
|
22282
|
+
throw new Error("--max-concurrent-rows requires a whole number.");
|
|
22283
|
+
}
|
|
22284
|
+
if (!/^[1-9]\d*$/.test(value)) {
|
|
22285
|
+
throw new Error(
|
|
22286
|
+
"--max-concurrent-rows requires a positive whole number."
|
|
22287
|
+
);
|
|
22288
|
+
}
|
|
22289
|
+
maxConcurrentRows = parsePositiveInteger3(value, "--max-concurrent-rows");
|
|
22290
|
+
resolveMaxConcurrentRows(maxConcurrentRows);
|
|
22291
|
+
index += 1;
|
|
22292
|
+
continue;
|
|
22293
|
+
}
|
|
21982
22294
|
if (arg === "--fixture-behavior") {
|
|
21983
22295
|
const value = args[index + 1];
|
|
21984
22296
|
if (!value) {
|
|
@@ -22089,11 +22401,14 @@ function parsePlayRunOptions(args) {
|
|
|
22089
22401
|
fullJson,
|
|
22090
22402
|
waitTimeoutMs,
|
|
22091
22403
|
force,
|
|
22092
|
-
|
|
22404
|
+
maxConcurrentExternalCalls,
|
|
22405
|
+
maxConcurrentRows,
|
|
22406
|
+
open: open2,
|
|
22093
22407
|
profile,
|
|
22094
22408
|
debugMapLatency,
|
|
22095
22409
|
debugFixtureProviderPacing,
|
|
22096
|
-
fixtureBehavior
|
|
22410
|
+
fixtureBehavior,
|
|
22411
|
+
runIdFile
|
|
22097
22412
|
};
|
|
22098
22413
|
}
|
|
22099
22414
|
function parsePlayCheckOptions(args) {
|
|
@@ -22776,6 +23091,8 @@ async function handleFileBackedRun(options, hooks) {
|
|
|
22776
23091
|
...stagedFileInputs.inputFile ? { inputFile: stagedFileInputs.inputFile } : {},
|
|
22777
23092
|
...stagedFileInputs.packagedFiles.length ? { packagedFiles: stagedFileInputs.packagedFiles } : {},
|
|
22778
23093
|
...options.force ? { force: true } : {},
|
|
23094
|
+
...options.maxConcurrentExternalCalls !== null ? { maxConcurrentExternalCalls: options.maxConcurrentExternalCalls } : {},
|
|
23095
|
+
...options.maxConcurrentRows !== null ? { maxConcurrentRows: options.maxConcurrentRows } : {},
|
|
22779
23096
|
...options.profile ? { profile: options.profile } : {},
|
|
22780
23097
|
...Object.keys(testPolicyOverrides).length > 0 ? { testPolicyOverrides } : {},
|
|
22781
23098
|
...integrationMode ? { integrationMode } : {},
|
|
@@ -22836,6 +23153,7 @@ async function handleFileBackedRun(options, hooks) {
|
|
|
22836
23153
|
throw await normalizePlayStartError(client2, error, playName);
|
|
22837
23154
|
})
|
|
22838
23155
|
);
|
|
23156
|
+
await hooks?.onRunStarted?.(started.workflowId);
|
|
22839
23157
|
const resolvedDashboardUrl = buildPlayDashboardUrl(client2.baseUrl, playName);
|
|
22840
23158
|
openPlayDashboard(resolvedDashboardUrl, options.open);
|
|
22841
23159
|
progress.phase("started run");
|
|
@@ -22956,6 +23274,8 @@ async function handleNamedRun(options, hooks) {
|
|
|
22956
23274
|
...stagedFileInputs.inputFile ? { inputFile: stagedFileInputs.inputFile } : {},
|
|
22957
23275
|
...stagedFileInputs.packagedFiles.length ? { packagedFiles: stagedFileInputs.packagedFiles } : {},
|
|
22958
23276
|
...options.force ? { force: true } : {},
|
|
23277
|
+
...options.maxConcurrentExternalCalls !== null ? { maxConcurrentExternalCalls: options.maxConcurrentExternalCalls } : {},
|
|
23278
|
+
...options.maxConcurrentRows !== null ? { maxConcurrentRows: options.maxConcurrentRows } : {},
|
|
22959
23279
|
...options.profile ? { profile: options.profile } : {},
|
|
22960
23280
|
...Object.keys(testPolicyOverrides).length > 0 ? { testPolicyOverrides } : {},
|
|
22961
23281
|
...integrationMode ? { integrationMode } : {},
|
|
@@ -23021,6 +23341,7 @@ async function handleNamedRun(options, hooks) {
|
|
|
23021
23341
|
});
|
|
23022
23342
|
})
|
|
23023
23343
|
);
|
|
23344
|
+
await hooks?.onRunStarted?.(started.workflowId);
|
|
23024
23345
|
const resolvedDashboardUrl = buildPlayDashboardUrl(client2.baseUrl, playName);
|
|
23025
23346
|
openPlayDashboard(resolvedDashboardUrl, options.open);
|
|
23026
23347
|
progress.phase("started run");
|
|
@@ -23037,10 +23358,28 @@ async function handleNamedRun(options, hooks) {
|
|
|
23037
23358
|
return 0;
|
|
23038
23359
|
}
|
|
23039
23360
|
async function handlePlayRun(args, hooks) {
|
|
23040
|
-
const
|
|
23361
|
+
const parsedOptions = parsePlayRunOptions(args);
|
|
23362
|
+
const options = parsedOptions.runIdFile ? {
|
|
23363
|
+
...parsedOptions,
|
|
23364
|
+
runIdFile: await preflightRunIdFile(parsedOptions.runIdFile)
|
|
23365
|
+
} : parsedOptions;
|
|
23366
|
+
const runHooks = options.runIdFile ? {
|
|
23367
|
+
...hooks,
|
|
23368
|
+
onRunStarted: async (runId) => {
|
|
23369
|
+
try {
|
|
23370
|
+
await writePlayRunIdFile(options.runIdFile, runId);
|
|
23371
|
+
} catch (error) {
|
|
23372
|
+
throw new Error(
|
|
23373
|
+
`Run ${runId} was accepted, but its identity could not be persisted to ${options.runIdFile}: ${error instanceof Error ? error.message : String(error)}. Inspect it with 'deepline runs get ${runId} --full --json'; do not submit a replacement run.`,
|
|
23374
|
+
{ cause: error }
|
|
23375
|
+
);
|
|
23376
|
+
}
|
|
23377
|
+
await hooks?.onRunStarted?.(runId);
|
|
23378
|
+
}
|
|
23379
|
+
} : hooks;
|
|
23041
23380
|
if (options.target.kind === "file") {
|
|
23042
23381
|
if (isFileTarget(options.target.path)) {
|
|
23043
|
-
return handleFileBackedRun(options,
|
|
23382
|
+
return handleFileBackedRun(options, runHooks);
|
|
23044
23383
|
}
|
|
23045
23384
|
const resolved = resolve11(options.target.path);
|
|
23046
23385
|
console.error(`File not found: ${resolved}`);
|
|
@@ -23062,7 +23401,7 @@ async function handlePlayRun(args, hooks) {
|
|
|
23062
23401
|
}
|
|
23063
23402
|
return 1;
|
|
23064
23403
|
}
|
|
23065
|
-
return handleNamedRun(options,
|
|
23404
|
+
return handleNamedRun(options, runHooks);
|
|
23066
23405
|
}
|
|
23067
23406
|
function parseRunIdPositional(args, usage) {
|
|
23068
23407
|
for (let index = 0; index < args.length; index += 1) {
|
|
@@ -24390,10 +24729,18 @@ Notes:
|
|
|
24390
24729
|
next commands. --watch and --wait are accepted compatibility aliases for the
|
|
24391
24730
|
default behavior. Use --no-wait only when you intentionally want
|
|
24392
24731
|
a fire-and-forget run id.
|
|
24732
|
+
--run-id-file writes the durable run id to a versioned JSON file as soon as
|
|
24733
|
+
the server accepts the run. The destination must not already exist.
|
|
24393
24734
|
The play page URL is printed when the run starts. Pass --open to open it in a browser.
|
|
24394
24735
|
Concurrent runs for the same play are allowed.
|
|
24395
24736
|
--force starts a fresh run graph without refreshing completed provider calls.
|
|
24396
24737
|
It does not cancel active sibling runs.
|
|
24738
|
+
--max-concurrent-external-calls controls the per-run provider-tool/ctx.fetch
|
|
24739
|
+
resident-work ceiling. Default: ${DEFAULT_MAX_CONCURRENT_EXTERNAL_CALLS}; accepted range: 1-${MAX_CONFIGURABLE_CONCURRENT_EXTERNAL_CALLS}.
|
|
24740
|
+
Provider pacing and sandbox memory limits still apply.
|
|
24741
|
+
--max-concurrent-rows sets the run-wide default and ceiling for live map row
|
|
24742
|
+
resolvers. Accepted range: 1-${MAX_CONFIGURABLE_CONCURRENT_ROWS}. The runtime
|
|
24743
|
+
may lower it when source-row size exceeds the active-row memory budget.
|
|
24397
24744
|
This command starts cloud work and may spend Deepline credits through tool calls.
|
|
24398
24745
|
|
|
24399
24746
|
Idempotent execution:
|
|
@@ -24429,8 +24776,10 @@ Idempotent execution:
|
|
|
24429
24776
|
Examples:
|
|
24430
24777
|
deepline plays run prebuilt/person-linkedin-to-email --input '{"linkedin_url":"..."}'
|
|
24431
24778
|
deepline plays run long-background-play --no-wait
|
|
24779
|
+
deepline plays run long-background-play --run-id-file ./run-id.json
|
|
24432
24780
|
deepline plays run my.play.ts --input '{"domain":"stripe.com"}'
|
|
24433
24781
|
deepline plays run my.play.ts --profile absurd
|
|
24782
|
+
deepline plays run my.play.ts --max-concurrent-external-calls 20
|
|
24434
24783
|
deepline plays run my.play.ts --input @input.json --json
|
|
24435
24784
|
deepline plays run cto-search.play.ts --limit 5
|
|
24436
24785
|
deepline runs export <run-id> --out output.csv
|
|
@@ -24446,9 +24795,18 @@ Examples:
|
|
|
24446
24795
|
"--fixture-behavior <json>",
|
|
24447
24796
|
"Internal/testing: fixture response behavior JSON object or @file path"
|
|
24448
24797
|
).option("--watch", "Compatibility alias; run waits by default").option("--wait", "Compatibility alias; run waits by default").option("--no-wait", "Start the run and return immediately").option(
|
|
24798
|
+
"--run-id-file <path>",
|
|
24799
|
+
"Atomically write the accepted run id to a new JSON file"
|
|
24800
|
+
).option(
|
|
24449
24801
|
"--logs",
|
|
24450
24802
|
"When output is non-interactive, stream play logs to stderr while waiting"
|
|
24451
|
-
).option("--tail-timeout-ms <ms>", "Timeout while watching the run stream").option("--force", "Start a fresh run graph").option(
|
|
24803
|
+
).option("--tail-timeout-ms <ms>", "Timeout while watching the run stream").option("--force", "Start a fresh run graph").option(
|
|
24804
|
+
"--max-concurrent-external-calls <count>",
|
|
24805
|
+
`Concurrent provider-tool and ctx.fetch executions (${DEFAULT_MAX_CONCURRENT_EXTERNAL_CALLS} default, max ${MAX_CONFIGURABLE_CONCURRENT_EXTERNAL_CALLS})`
|
|
24806
|
+
).option(
|
|
24807
|
+
"--max-concurrent-rows <count>",
|
|
24808
|
+
`Run-wide dataset map row resolver ceiling (max ${MAX_CONFIGURABLE_CONCURRENT_ROWS})`
|
|
24809
|
+
).option("--open", "Open the play page in a browser after the run starts").option(
|
|
24452
24810
|
"--debug-map-latency",
|
|
24453
24811
|
"Internal diagnostics: emit one aggregate latency profile per dataset map"
|
|
24454
24812
|
).option(
|
|
@@ -24487,10 +24845,16 @@ Pass-through input flags:
|
|
|
24487
24845
|
...options.profile ? ["--profile", options.profile] : [],
|
|
24488
24846
|
...options.fixtureBehavior ? ["--fixture-behavior", options.fixtureBehavior] : [],
|
|
24489
24847
|
...options.wait === false ? ["--no-wait"] : [],
|
|
24848
|
+
...options.runIdFile ? ["--run-id-file", options.runIdFile] : [],
|
|
24490
24849
|
...options.watch || options.wait ? ["--watch"] : [],
|
|
24491
24850
|
...options.logs ? ["--logs"] : [],
|
|
24492
24851
|
...options.tailTimeoutMs ? ["--tail-timeout-ms", options.tailTimeoutMs] : [],
|
|
24493
24852
|
...options.force ? ["--force"] : [],
|
|
24853
|
+
...options.maxConcurrentExternalCalls ? [
|
|
24854
|
+
"--max-concurrent-external-calls",
|
|
24855
|
+
options.maxConcurrentExternalCalls
|
|
24856
|
+
] : [],
|
|
24857
|
+
...options.maxConcurrentRows ? ["--max-concurrent-rows", options.maxConcurrentRows] : [],
|
|
24494
24858
|
...options.open ? ["--open"] : [],
|
|
24495
24859
|
...options.debugMapLatency ? ["--debug-map-latency"] : [],
|
|
24496
24860
|
...options.debugFixtureProviderPacing ? ["--debug-fixture-provider-pacing"] : [],
|
|
@@ -30266,7 +30630,7 @@ function registerEnrichCommand(program) {
|
|
|
30266
30630
|
let inPlaceTempDir = null;
|
|
30267
30631
|
let inPlaceTempOutputPath = null;
|
|
30268
30632
|
const inPlaceFinalOutputPath = options.inPlace ? resolve12(inputCsv) : null;
|
|
30269
|
-
const inPlaceCommitOutputPath = options.inPlace ? (await
|
|
30633
|
+
const inPlaceCommitOutputPath = options.inPlace ? (await lstat2(inputCsv)).isSymbolicLink() ? await realpath2(inputCsv) : inPlaceFinalOutputPath : null;
|
|
30270
30634
|
const failureReportOutputPath = options.inPlace ? inPlaceFinalOutputPath : null;
|
|
30271
30635
|
const enrichIssueFollowUpOutputPath = options.inPlace && inPlaceFinalOutputPath ? sidecarEnrichRowsExportPath(inPlaceFinalOutputPath) : null;
|
|
30272
30636
|
let activeRunId2 = null;
|
|
@@ -30581,7 +30945,7 @@ import {
|
|
|
30581
30945
|
import { homedir as homedir8, platform } from "os";
|
|
30582
30946
|
import { basename as basename5, dirname as dirname11, join as join12, resolve as resolve13 } from "path";
|
|
30583
30947
|
import { gzipSync } from "zlib";
|
|
30584
|
-
import { randomUUID as
|
|
30948
|
+
import { randomUUID as randomUUID4 } from "crypto";
|
|
30585
30949
|
var UUID_RE = /^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i;
|
|
30586
30950
|
var UUID_IN_TEXT_RE = /[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}/i;
|
|
30587
30951
|
var MAX_SESSION_UPLOAD_BYTES = 35e5;
|
|
@@ -30980,7 +31344,7 @@ async function uploadPayload(path, payload) {
|
|
|
30980
31344
|
return await http.post(path, payload);
|
|
30981
31345
|
}
|
|
30982
31346
|
async function uploadChunkedSessions(sessions, options) {
|
|
30983
|
-
const uploadId =
|
|
31347
|
+
const uploadId = randomUUID4();
|
|
30984
31348
|
for (const session of sessions) {
|
|
30985
31349
|
const bytes = Buffer.from(session.encodedContent, "base64");
|
|
30986
31350
|
const chunks = [];
|