deepline 0.1.182 → 0.1.184
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/apps/play-runner-workers/src/child-play-await.ts +203 -6
- package/dist/bundling-sources/apps/play-runner-workers/src/child-play-submit.ts +8 -1
- package/dist/bundling-sources/apps/play-runner-workers/src/coordinator-entry.ts +639 -109
- package/dist/bundling-sources/apps/play-runner-workers/src/dedup-do.ts +3 -2
- package/dist/bundling-sources/apps/play-runner-workers/src/entry.ts +1752 -1899
- package/dist/bundling-sources/apps/play-runner-workers/src/runtime/harness-receipt-store.ts +116 -0
- package/dist/bundling-sources/apps/play-runner-workers/src/runtime/map-chunk-plan.ts +542 -78
- package/dist/bundling-sources/apps/play-runner-workers/src/runtime/receipts.ts +292 -11
- package/dist/bundling-sources/apps/play-runner-workers/src/runtime/run-work-dispatcher.ts +519 -0
- package/dist/bundling-sources/apps/play-runner-workers/src/runtime/tool-dispatch.ts +2381 -0
- package/dist/bundling-sources/apps/play-runner-workers/src/runtime/tool-receipts.ts +18 -5
- package/dist/bundling-sources/apps/play-runner-workers/src/runtime/work-budget.ts +130 -0
- package/dist/bundling-sources/apps/play-runner-workers/src/runtime/worker-platform-budget.ts +39 -0
- package/dist/bundling-sources/apps/play-runner-workers/src/workflow-retry-state.ts +2 -0
- package/dist/bundling-sources/sdk/src/client.ts +41 -0
- package/dist/bundling-sources/sdk/src/http.ts +23 -8
- package/dist/bundling-sources/sdk/src/plays/harness-stub.ts +56 -3
- package/dist/bundling-sources/sdk/src/release.ts +2 -2
- package/dist/bundling-sources/sdk/src/types.ts +2 -0
- package/dist/bundling-sources/shared_libs/play-runtime/app-runtime-api.ts +133 -10
- package/dist/bundling-sources/shared_libs/play-runtime/auth-scope-resolver.ts +92 -0
- package/dist/bundling-sources/shared_libs/play-runtime/batch-runtime.ts +4 -4
- package/dist/bundling-sources/shared_libs/play-runtime/batching-types.ts +8 -0
- package/dist/bundling-sources/shared_libs/play-runtime/child-run-id.ts +101 -0
- package/dist/bundling-sources/shared_libs/play-runtime/context.ts +1612 -287
- package/dist/bundling-sources/shared_libs/play-runtime/ctx-types.ts +105 -6
- package/dist/bundling-sources/shared_libs/play-runtime/dedup-backend.ts +0 -0
- package/dist/bundling-sources/shared_libs/play-runtime/default-batch-strategies.ts +1 -0
- package/dist/bundling-sources/shared_libs/play-runtime/durability-store.ts +4 -0
- package/dist/bundling-sources/shared_libs/play-runtime/durable-call-cache.ts +116 -16
- package/dist/bundling-sources/shared_libs/play-runtime/durable-receipt-execution.ts +186 -20
- package/dist/bundling-sources/shared_libs/play-runtime/dynamic-worker-version.ts +2 -0
- package/dist/bundling-sources/shared_libs/play-runtime/execution-ledger-store.ts +133 -0
- package/dist/bundling-sources/shared_libs/play-runtime/governor/app-runtime-rate-state-backend.ts +245 -0
- package/dist/bundling-sources/shared_libs/play-runtime/governor/governor.ts +5 -5
- package/dist/bundling-sources/shared_libs/play-runtime/governor/policy.ts +14 -0
- package/dist/bundling-sources/shared_libs/play-runtime/lease-policy.ts +52 -0
- package/dist/bundling-sources/shared_libs/play-runtime/protocol.ts +41 -0
- package/dist/bundling-sources/shared_libs/play-runtime/providers.ts +3 -2
- package/dist/bundling-sources/shared_libs/play-runtime/receipt-sql.ts +124 -0
- package/dist/bundling-sources/shared_libs/play-runtime/receipt-status.ts +6 -2
- package/dist/bundling-sources/shared_libs/play-runtime/row-isolation.ts +48 -2
- package/dist/bundling-sources/shared_libs/play-runtime/run-ledger.ts +158 -15
- package/dist/bundling-sources/shared_libs/play-runtime/run-terminal-source.ts +45 -0
- package/dist/bundling-sources/shared_libs/play-runtime/runtime-actions.ts +9 -0
- package/dist/bundling-sources/shared_libs/play-runtime/runtime-api-paths.ts +21 -0
- package/dist/bundling-sources/shared_libs/play-runtime/runtime-api.ts +2038 -262
- package/dist/bundling-sources/shared_libs/play-runtime/runtime-contract.ts +42 -0
- package/dist/bundling-sources/shared_libs/play-runtime/runtime-sheet-attempt-state-machine.ts +183 -0
- package/dist/bundling-sources/shared_libs/play-runtime/runtime-sheet-errors.ts +88 -0
- package/dist/bundling-sources/shared_libs/play-runtime/scheduler-backend.ts +8 -1
- package/dist/bundling-sources/shared_libs/play-runtime/sheet-attempt-sql.ts +103 -0
- package/dist/bundling-sources/shared_libs/play-runtime/suspension.ts +19 -1
- package/dist/bundling-sources/shared_libs/play-runtime/test-runtime-seams.ts +343 -0
- package/dist/bundling-sources/shared_libs/play-runtime/tool-execute-retry-policy.ts +43 -0
- package/dist/bundling-sources/shared_libs/play-runtime/tool-http-errors.ts +11 -0
- package/dist/bundling-sources/shared_libs/play-runtime/work-receipt-state-machine.ts +437 -0
- package/dist/bundling-sources/shared_libs/play-runtime/work-receipts.ts +83 -6
- package/dist/bundling-sources/shared_libs/plays/bundling/index.ts +28 -11
- package/dist/bundling-sources/shared_libs/plays/static-pipeline.ts +38 -6
- package/dist/bundling-sources/shared_libs/security/safe-outbound-fetch.ts +24 -17
- package/dist/cli/index.js +76 -17
- package/dist/cli/index.mjs +76 -17
- package/dist/index.d.mts +2 -0
- package/dist/index.d.ts +2 -0
- package/dist/index.js +63 -9
- package/dist/index.mjs +63 -9
- package/dist/plays/bundle-play-file.mjs +20 -6
- package/package.json +1 -1
|
@@ -22,7 +22,10 @@ import {
|
|
|
22
22
|
type WorkflowRunner,
|
|
23
23
|
} from '@cloudflare/dynamic-workflows';
|
|
24
24
|
import type { ExecutionPlan } from '../../../shared_libs/play-runtime/execution-plan';
|
|
25
|
+
import { buildChildRunId as buildSharedChildRunId } from '../../../shared_libs/play-runtime/child-run-id';
|
|
25
26
|
import type { PlayCallGovernanceSnapshot } from '../../../shared_libs/play-runtime/scheduler-backend';
|
|
27
|
+
import type { RuntimeTestPolicyOverrides } from '../../../shared_libs/play-runtime/test-runtime-seams';
|
|
28
|
+
import { DYNAMIC_PLAY_WORKER_ARTIFACT_VERSION } from '../../../shared_libs/play-runtime/dynamic-worker-version';
|
|
26
29
|
import {
|
|
27
30
|
DB_SESSION_DEFAULT_TTL_SECONDS,
|
|
28
31
|
createDbSessionResponseSchema,
|
|
@@ -54,6 +57,15 @@ import {
|
|
|
54
57
|
COORDINATOR_INTERNAL_TOKEN_HEADER,
|
|
55
58
|
COORDINATOR_RUN_SCOPE_HEADER,
|
|
56
59
|
} from '../../../shared_libs/play-runtime/coordinator-headers';
|
|
60
|
+
import {
|
|
61
|
+
PLAY_RUNTIME_CONTRACT,
|
|
62
|
+
PLAY_RUNTIME_CONTRACT_HEADER,
|
|
63
|
+
} from '../../../shared_libs/play-runtime/runtime-contract';
|
|
64
|
+
import {
|
|
65
|
+
PLAY_RUNTIME_API_COMPAT_PATH,
|
|
66
|
+
PLAY_RUNTIME_CHILD_EXECUTOR_TOKEN_COMPAT_PATH,
|
|
67
|
+
PLAY_RUNTIME_TAIL_LOG_COMPAT_PATH,
|
|
68
|
+
} from '../../../shared_libs/play-runtime/runtime-api-paths';
|
|
57
69
|
import {
|
|
58
70
|
decideWorkflowPlatformRetry,
|
|
59
71
|
PLATFORM_DEPLOY_WORKFLOW_RETRY_LIMIT,
|
|
@@ -85,6 +97,8 @@ export type PlayWorkflowParams = {
|
|
|
85
97
|
artifactHash: string;
|
|
86
98
|
graphHash: string;
|
|
87
99
|
input: Record<string, unknown>;
|
|
100
|
+
force?: boolean;
|
|
101
|
+
runAttempt?: number;
|
|
88
102
|
inputFile?: {
|
|
89
103
|
name?: string;
|
|
90
104
|
r2Key?: string;
|
|
@@ -126,6 +140,8 @@ export type PlayWorkflowParams = {
|
|
|
126
140
|
totalRows?: number;
|
|
127
141
|
coordinatorUrl?: string | null;
|
|
128
142
|
coordinatorInternalToken?: string | null;
|
|
143
|
+
runtimeTestFaultHeader?: string | null;
|
|
144
|
+
testPolicyOverrides?: RuntimeTestPolicyOverrides | null;
|
|
129
145
|
submittedAt?: number | null;
|
|
130
146
|
};
|
|
131
147
|
|
|
@@ -649,6 +665,9 @@ const SUBMIT_INITIAL_STATE_POLL_MS = 50;
|
|
|
649
665
|
const WORKFLOW_RETRY_STATE_TTL_MS = 60 * 60 * 1000;
|
|
650
666
|
const WORKFLOW_SUBMIT_DUPLICATE_WAIT_MS = 55_000;
|
|
651
667
|
const WORKFLOW_SUBMIT_DUPLICATE_POLL_MS = 250;
|
|
668
|
+
const CHILD_WORKFLOW_SUBMIT_RETRY_DELAYS_MS = [
|
|
669
|
+
250, 750, 1500, 3000, 5000, 10000,
|
|
670
|
+
] as const;
|
|
652
671
|
const COORDINATOR_WORKER_MEMORY_LIMIT_MESSAGE =
|
|
653
672
|
'Worker memory limit hit before the run could finish. For CSV enrich, use --output or --in-place for automatic batches; otherwise rerun smaller --rows ranges.';
|
|
654
673
|
|
|
@@ -668,7 +687,7 @@ function buildDynamicWorkflowMetadata(
|
|
|
668
687
|
graphHash: params.graphHash,
|
|
669
688
|
artifactStorageKey: params.artifactStorageKey,
|
|
670
689
|
artifactHash: params.artifactHash ?? null,
|
|
671
|
-
dynamicWorkerCode:
|
|
690
|
+
dynamicWorkerCode: null,
|
|
672
691
|
integrationMode: normalizeIntegrationMode(params.integrationMode),
|
|
673
692
|
packagedFiles: normalizePackagedFiles(params.packagedFiles),
|
|
674
693
|
};
|
|
@@ -746,10 +765,11 @@ async function createDynamicWorkflowInstance(input: {
|
|
|
746
765
|
env: CoordinatorEnv;
|
|
747
766
|
id: string;
|
|
748
767
|
params: PlayWorkflowParams;
|
|
768
|
+
metadataParams?: PlayWorkflowParams;
|
|
749
769
|
}): Promise<WorkflowInstance> {
|
|
750
770
|
const workflow = createDispatcherWorkflowBinding(
|
|
751
771
|
() => input.env.PLAY_WORKFLOW as unknown as Workflow,
|
|
752
|
-
buildDynamicWorkflowMetadata(input.params),
|
|
772
|
+
buildDynamicWorkflowMetadata(input.metadataParams ?? input.params),
|
|
753
773
|
);
|
|
754
774
|
return workflow.create({
|
|
755
775
|
id: input.id,
|
|
@@ -1127,6 +1147,96 @@ async function hydrateWorkflowDbSessions(input: {
|
|
|
1127
1147
|
};
|
|
1128
1148
|
}
|
|
1129
1149
|
|
|
1150
|
+
async function hydrateWorkflowLaunchParams(input: {
|
|
1151
|
+
env: CoordinatorEnv;
|
|
1152
|
+
event: unknown;
|
|
1153
|
+
trace: CoordinatorPerfTraceSink;
|
|
1154
|
+
}): Promise<unknown> {
|
|
1155
|
+
if (!isRecord(input.event)) return input.event;
|
|
1156
|
+
const payload = isRecord(input.event.payload) ? input.event.payload : null;
|
|
1157
|
+
const envelopeParams = isRecord(payload?.params) ? payload.params : null;
|
|
1158
|
+
const params = envelopeParams ?? payload;
|
|
1159
|
+
if (
|
|
1160
|
+
!payload ||
|
|
1161
|
+
!params ||
|
|
1162
|
+
(!isRecord(params.workflowParams) && !isRecord(params.workflowParamsRef))
|
|
1163
|
+
) {
|
|
1164
|
+
return input.event;
|
|
1165
|
+
}
|
|
1166
|
+
const startedAt = Date.now();
|
|
1167
|
+
const hydrated = await hydrateWorkflowRetryParams({
|
|
1168
|
+
env: input.env,
|
|
1169
|
+
params: params.workflowParams,
|
|
1170
|
+
paramsRef: params.workflowParamsRef,
|
|
1171
|
+
});
|
|
1172
|
+
if (!hydrated) return input.event;
|
|
1173
|
+
const submittedAt =
|
|
1174
|
+
typeof params.submittedAt === 'number' &&
|
|
1175
|
+
Number.isFinite(params.submittedAt)
|
|
1176
|
+
? params.submittedAt
|
|
1177
|
+
: hydrated.submittedAt;
|
|
1178
|
+
const hydratedParams = {
|
|
1179
|
+
...hydrated,
|
|
1180
|
+
submittedAt,
|
|
1181
|
+
};
|
|
1182
|
+
input.trace({
|
|
1183
|
+
runId:
|
|
1184
|
+
typeof hydratedParams.runId === 'string'
|
|
1185
|
+
? hydratedParams.runId
|
|
1186
|
+
: 'unknown-workflow-run',
|
|
1187
|
+
phase: 'coordinator.workflow_launch_params_hydrated',
|
|
1188
|
+
ms: Date.now() - startedAt,
|
|
1189
|
+
graphHash:
|
|
1190
|
+
typeof hydratedParams.graphHash === 'string'
|
|
1191
|
+
? hydratedParams.graphHash
|
|
1192
|
+
: null,
|
|
1193
|
+
extra: {
|
|
1194
|
+
paramsBytes: isRecord(params.workflowParamsRef)
|
|
1195
|
+
? typeof params.workflowParamsRef.bytes === 'number'
|
|
1196
|
+
? params.workflowParamsRef.bytes
|
|
1197
|
+
: null
|
|
1198
|
+
: jsonByteLength(params.workflowParams),
|
|
1199
|
+
paramsStorage: isRecord(params.workflowParamsRef) ? 'r2' : 'inline',
|
|
1200
|
+
},
|
|
1201
|
+
});
|
|
1202
|
+
return {
|
|
1203
|
+
...input.event,
|
|
1204
|
+
payload: envelopeParams
|
|
1205
|
+
? {
|
|
1206
|
+
...payload,
|
|
1207
|
+
params: hydratedParams,
|
|
1208
|
+
}
|
|
1209
|
+
: {
|
|
1210
|
+
...payload,
|
|
1211
|
+
...hydratedParams,
|
|
1212
|
+
},
|
|
1213
|
+
};
|
|
1214
|
+
}
|
|
1215
|
+
|
|
1216
|
+
function workflowCreateParams(
|
|
1217
|
+
params: PlayWorkflowParams,
|
|
1218
|
+
launchState: {
|
|
1219
|
+
params?: PlayWorkflowParams;
|
|
1220
|
+
paramsRef?: WorkflowRetryParamsRef;
|
|
1221
|
+
},
|
|
1222
|
+
): PlayWorkflowParams {
|
|
1223
|
+
const launchParams = launchState.params ?? params;
|
|
1224
|
+
const envelope: Record<string, unknown> = {
|
|
1225
|
+
runId: params.runId,
|
|
1226
|
+
playName: params.playName,
|
|
1227
|
+
graphHash: params.graphHash,
|
|
1228
|
+
artifactStorageKey: params.artifactStorageKey,
|
|
1229
|
+
artifactHash: params.artifactHash,
|
|
1230
|
+
submittedAt: params.submittedAt,
|
|
1231
|
+
};
|
|
1232
|
+
if (launchState.paramsRef) {
|
|
1233
|
+
envelope.workflowParamsRef = launchState.paramsRef;
|
|
1234
|
+
} else {
|
|
1235
|
+
envelope.workflowParams = launchParams;
|
|
1236
|
+
}
|
|
1237
|
+
return envelope as unknown as PlayWorkflowParams;
|
|
1238
|
+
}
|
|
1239
|
+
|
|
1130
1240
|
function sleep(ms: number): Promise<void> {
|
|
1131
1241
|
return new Promise((resolve) => setTimeout(resolve, ms));
|
|
1132
1242
|
}
|
|
@@ -1209,7 +1319,7 @@ async function markWorkflowRuntimeFailure(input: {
|
|
|
1209
1319
|
} satisfies PlayRunLedgerEvent,
|
|
1210
1320
|
],
|
|
1211
1321
|
});
|
|
1212
|
-
const url = `${baseUrl.replace(/\/$/, '')}
|
|
1322
|
+
const url = `${baseUrl.replace(/\/$/, '')}${PLAY_RUNTIME_API_COMPAT_PATH}`;
|
|
1213
1323
|
const backoffMs = [200, 500, 1500];
|
|
1214
1324
|
let lastError: unknown = null;
|
|
1215
1325
|
for (let attempt = 0; attempt <= backoffMs.length; attempt += 1) {
|
|
@@ -1240,6 +1350,47 @@ async function markWorkflowRuntimeFailure(input: {
|
|
|
1240
1350
|
});
|
|
1241
1351
|
}
|
|
1242
1352
|
|
|
1353
|
+
async function appendWorkflowChildCompletedRunEvent(input: {
|
|
1354
|
+
env: CoordinatorEnv;
|
|
1355
|
+
event: unknown;
|
|
1356
|
+
result: unknown;
|
|
1357
|
+
}): Promise<boolean> {
|
|
1358
|
+
const payload = readWorkflowPayload(input.event);
|
|
1359
|
+
if (!payload || !isRecord(payload.playCallGovernance)) return false;
|
|
1360
|
+
const runId = typeof payload.runId === 'string' ? payload.runId : null;
|
|
1361
|
+
const baseUrl = typeof payload.baseUrl === 'string' ? payload.baseUrl : null;
|
|
1362
|
+
const executorToken =
|
|
1363
|
+
typeof payload.executorToken === 'string' ? payload.executorToken : null;
|
|
1364
|
+
if (!runId || !baseUrl || !executorToken) return false;
|
|
1365
|
+
const headers = new Headers({
|
|
1366
|
+
authorization: `Bearer ${executorToken}`,
|
|
1367
|
+
'content-type': 'application/json',
|
|
1368
|
+
});
|
|
1369
|
+
const bypass = input.env.VERCEL_PROTECTION_BYPASS_TOKEN?.trim();
|
|
1370
|
+
if (bypass) headers.set('x-vercel-protection-bypass', bypass);
|
|
1371
|
+
const body = JSON.stringify({
|
|
1372
|
+
action: 'append_run_events',
|
|
1373
|
+
playId: runId,
|
|
1374
|
+
events: [
|
|
1375
|
+
{
|
|
1376
|
+
type: 'run.completed',
|
|
1377
|
+
runId,
|
|
1378
|
+
source: 'worker',
|
|
1379
|
+
occurredAt: Date.now(),
|
|
1380
|
+
result: input.result,
|
|
1381
|
+
} satisfies PlayRunLedgerEvent,
|
|
1382
|
+
],
|
|
1383
|
+
});
|
|
1384
|
+
const url = `${baseUrl.replace(/\/$/, '')}${PLAY_RUNTIME_API_COMPAT_PATH}`;
|
|
1385
|
+
const response = await fetch(url, { method: 'POST', headers, body });
|
|
1386
|
+
if (!response.ok) {
|
|
1387
|
+
throw new Error(
|
|
1388
|
+
`runtime API responded ${response.status}: ${(await response.text().catch(() => '')).slice(0, 400)}`,
|
|
1389
|
+
);
|
|
1390
|
+
}
|
|
1391
|
+
return true;
|
|
1392
|
+
}
|
|
1393
|
+
|
|
1243
1394
|
type StoredPlayArtifactPayload = {
|
|
1244
1395
|
artifact?: {
|
|
1245
1396
|
bundledCode?: string;
|
|
@@ -1253,7 +1404,10 @@ async function persistWorkflowRetryState(input: {
|
|
|
1253
1404
|
env: CoordinatorEnv;
|
|
1254
1405
|
runId: string;
|
|
1255
1406
|
params: PlayWorkflowParams;
|
|
1256
|
-
}): Promise<
|
|
1407
|
+
}): Promise<{
|
|
1408
|
+
params?: PlayWorkflowParams;
|
|
1409
|
+
paramsRef?: WorkflowRetryParamsRef;
|
|
1410
|
+
}> {
|
|
1257
1411
|
const retryParams = buildWorkflowRetryParams(input.params);
|
|
1258
1412
|
const paramsBytes = jsonByteLength(retryParams);
|
|
1259
1413
|
if (paramsBytes > WORKFLOW_RETRY_PARAMS_MAX_BYTES) {
|
|
@@ -1275,21 +1429,32 @@ async function persistWorkflowRetryState(input: {
|
|
|
1275
1429
|
runId: input.runId,
|
|
1276
1430
|
hash,
|
|
1277
1431
|
});
|
|
1432
|
+
const paramsRef: WorkflowRetryParamsRef = {
|
|
1433
|
+
storageKind: 'r2',
|
|
1434
|
+
storageKey,
|
|
1435
|
+
bytes: paramsBytes,
|
|
1436
|
+
hash,
|
|
1437
|
+
expiresAt: Date.now() + WORKFLOW_RETRY_STATE_TTL_MS,
|
|
1438
|
+
};
|
|
1278
1439
|
await input.env.PLAYS_BUCKET.put(storageKey, serialized, {
|
|
1279
1440
|
httpMetadata: { contentType: 'application/json' },
|
|
1280
1441
|
});
|
|
1281
1442
|
body = {
|
|
1282
1443
|
runId: input.runId,
|
|
1283
|
-
paramsRef
|
|
1284
|
-
storageKind: 'r2',
|
|
1285
|
-
storageKey,
|
|
1286
|
-
bytes: paramsBytes,
|
|
1287
|
-
hash,
|
|
1288
|
-
expiresAt: Date.now() + WORKFLOW_RETRY_STATE_TTL_MS,
|
|
1289
|
-
},
|
|
1444
|
+
paramsRef,
|
|
1290
1445
|
paramsBytes,
|
|
1291
1446
|
ttlMs: WORKFLOW_RETRY_STATE_TTL_MS,
|
|
1292
1447
|
};
|
|
1448
|
+
await callRunScopedControl<{ ok?: unknown }>(
|
|
1449
|
+
input.env,
|
|
1450
|
+
input.runId,
|
|
1451
|
+
'/run-retry-state-put',
|
|
1452
|
+
{
|
|
1453
|
+
method: 'POST',
|
|
1454
|
+
body: JSON.stringify(body),
|
|
1455
|
+
},
|
|
1456
|
+
);
|
|
1457
|
+
return { paramsRef };
|
|
1293
1458
|
} else {
|
|
1294
1459
|
body = {
|
|
1295
1460
|
runId: input.runId,
|
|
@@ -1307,6 +1472,7 @@ async function persistWorkflowRetryState(input: {
|
|
|
1307
1472
|
body: JSON.stringify(body),
|
|
1308
1473
|
},
|
|
1309
1474
|
);
|
|
1475
|
+
return { params: retryParams };
|
|
1310
1476
|
}
|
|
1311
1477
|
|
|
1312
1478
|
async function persistWorkflowLaunchState(input: {
|
|
@@ -1318,14 +1484,16 @@ async function persistWorkflowLaunchState(input: {
|
|
|
1318
1484
|
retryExpiresAt?: number;
|
|
1319
1485
|
dbSessionsExpiresAt?: number;
|
|
1320
1486
|
sessionCount?: number;
|
|
1487
|
+
params?: PlayWorkflowParams;
|
|
1488
|
+
paramsRef?: WorkflowRetryParamsRef;
|
|
1321
1489
|
}> {
|
|
1322
1490
|
if (input.sessions.length === 0) {
|
|
1323
|
-
await persistWorkflowRetryState({
|
|
1491
|
+
const state = await persistWorkflowRetryState({
|
|
1324
1492
|
env: input.env,
|
|
1325
1493
|
runId: input.runId,
|
|
1326
1494
|
params: input.params,
|
|
1327
1495
|
});
|
|
1328
|
-
return
|
|
1496
|
+
return state;
|
|
1329
1497
|
}
|
|
1330
1498
|
const retryParams = buildWorkflowRetryParams(input.params);
|
|
1331
1499
|
const paramsBytes = jsonByteLength(retryParams);
|
|
@@ -1345,18 +1513,19 @@ async function persistWorkflowLaunchState(input: {
|
|
|
1345
1513
|
runId: input.runId,
|
|
1346
1514
|
hash,
|
|
1347
1515
|
});
|
|
1516
|
+
const paramsRef: WorkflowRetryParamsRef = {
|
|
1517
|
+
storageKind: 'r2',
|
|
1518
|
+
storageKey,
|
|
1519
|
+
bytes: paramsBytes,
|
|
1520
|
+
hash,
|
|
1521
|
+
expiresAt: Date.now() + WORKFLOW_RETRY_STATE_TTL_MS,
|
|
1522
|
+
};
|
|
1348
1523
|
await input.env.PLAYS_BUCKET.put(storageKey, serialized, {
|
|
1349
1524
|
httpMetadata: { contentType: 'application/json' },
|
|
1350
1525
|
});
|
|
1351
1526
|
body = {
|
|
1352
1527
|
runId: input.runId,
|
|
1353
|
-
paramsRef
|
|
1354
|
-
storageKind: 'r2',
|
|
1355
|
-
storageKey,
|
|
1356
|
-
bytes: paramsBytes,
|
|
1357
|
-
hash,
|
|
1358
|
-
expiresAt: Date.now() + WORKFLOW_RETRY_STATE_TTL_MS,
|
|
1359
|
-
},
|
|
1528
|
+
paramsRef,
|
|
1360
1529
|
paramsBytes,
|
|
1361
1530
|
sessions: input.sessions,
|
|
1362
1531
|
retryTtlMs: WORKFLOW_RETRY_STATE_TTL_MS,
|
|
@@ -1394,24 +1563,22 @@ async function persistWorkflowLaunchState(input: {
|
|
|
1394
1563
|
typeof response.sessionCount === 'number'
|
|
1395
1564
|
? response.sessionCount
|
|
1396
1565
|
: undefined,
|
|
1566
|
+
params: body.params,
|
|
1567
|
+
paramsRef: body.paramsRef,
|
|
1397
1568
|
};
|
|
1398
1569
|
}
|
|
1399
1570
|
|
|
1400
|
-
|
|
1401
|
-
|
|
1402
|
-
|
|
1403
|
-
paramsRef
|
|
1404
|
-
}): Promise<PlayWorkflowParams | null> {
|
|
1405
|
-
if (isRecord(input.params)) {
|
|
1406
|
-
return input.params as PlayWorkflowParams;
|
|
1407
|
-
}
|
|
1408
|
-
if (!isRecord(input.paramsRef)) {
|
|
1571
|
+
function parseWorkflowRetryParamsRef(
|
|
1572
|
+
paramsRef: unknown,
|
|
1573
|
+
): WorkflowRetryParamsRef | null {
|
|
1574
|
+
if (!isRecord(paramsRef)) {
|
|
1409
1575
|
return null;
|
|
1410
1576
|
}
|
|
1411
|
-
const storageKind =
|
|
1412
|
-
const storageKey =
|
|
1413
|
-
const expectedBytes =
|
|
1414
|
-
const expectedHash =
|
|
1577
|
+
const storageKind = paramsRef.storageKind;
|
|
1578
|
+
const storageKey = paramsRef.storageKey;
|
|
1579
|
+
const expectedBytes = paramsRef.bytes;
|
|
1580
|
+
const expectedHash = paramsRef.hash;
|
|
1581
|
+
const expiresAt = paramsRef.expiresAt;
|
|
1415
1582
|
if (
|
|
1416
1583
|
storageKind !== 'r2' ||
|
|
1417
1584
|
typeof storageKey !== 'string' ||
|
|
@@ -1419,10 +1586,37 @@ async function hydrateWorkflowRetryParams(input: {
|
|
|
1419
1586
|
typeof expectedBytes !== 'number' ||
|
|
1420
1587
|
!Number.isFinite(expectedBytes) ||
|
|
1421
1588
|
typeof expectedHash !== 'string' ||
|
|
1422
|
-
!expectedHash
|
|
1589
|
+
!expectedHash ||
|
|
1590
|
+
typeof expiresAt !== 'number' ||
|
|
1591
|
+
!Number.isFinite(expiresAt)
|
|
1423
1592
|
) {
|
|
1424
1593
|
throw new Error('Invalid workflow retry params reference.');
|
|
1425
1594
|
}
|
|
1595
|
+
return {
|
|
1596
|
+
storageKind,
|
|
1597
|
+
storageKey,
|
|
1598
|
+
bytes: expectedBytes,
|
|
1599
|
+
hash: expectedHash,
|
|
1600
|
+
expiresAt,
|
|
1601
|
+
};
|
|
1602
|
+
}
|
|
1603
|
+
|
|
1604
|
+
async function hydrateWorkflowRetryParams(input: {
|
|
1605
|
+
env: CoordinatorEnv;
|
|
1606
|
+
params: unknown;
|
|
1607
|
+
paramsRef: unknown;
|
|
1608
|
+
}): Promise<PlayWorkflowParams | null> {
|
|
1609
|
+
if (isRecord(input.params)) {
|
|
1610
|
+
return input.params as PlayWorkflowParams;
|
|
1611
|
+
}
|
|
1612
|
+
const paramsRef = parseWorkflowRetryParamsRef(input.paramsRef);
|
|
1613
|
+
if (!paramsRef) return null;
|
|
1614
|
+
const storageKey = paramsRef.storageKey;
|
|
1615
|
+
const expectedBytes = paramsRef.bytes;
|
|
1616
|
+
const expectedHash = paramsRef.hash;
|
|
1617
|
+
if (paramsRef.expiresAt <= Date.now()) {
|
|
1618
|
+
throw new Error('Workflow retry params reference expired.');
|
|
1619
|
+
}
|
|
1426
1620
|
const object = await input.env.PLAYS_BUCKET.get(storageKey);
|
|
1427
1621
|
if (!object) {
|
|
1428
1622
|
throw new Error(`Workflow retry params missing from R2: ${storageKey}`);
|
|
@@ -1470,6 +1664,7 @@ async function claimWorkflowPlatformRetry(input: {
|
|
|
1470
1664
|
claimed: boolean;
|
|
1471
1665
|
attempts: number;
|
|
1472
1666
|
params: PlayWorkflowParams | null;
|
|
1667
|
+
paramsRef?: WorkflowRetryParamsRef;
|
|
1473
1668
|
}> {
|
|
1474
1669
|
const body = await callRunScopedControl<{
|
|
1475
1670
|
claimed?: unknown;
|
|
@@ -1488,10 +1683,12 @@ async function claimWorkflowPlatformRetry(input: {
|
|
|
1488
1683
|
params: body.params,
|
|
1489
1684
|
paramsRef: body.paramsRef,
|
|
1490
1685
|
});
|
|
1686
|
+
const paramsRef = parseWorkflowRetryParamsRef(body.paramsRef) ?? undefined;
|
|
1491
1687
|
return {
|
|
1492
1688
|
claimed: body.claimed === true,
|
|
1493
1689
|
attempts: typeof body.attempts === 'number' ? body.attempts : 0,
|
|
1494
1690
|
params,
|
|
1691
|
+
paramsRef,
|
|
1495
1692
|
};
|
|
1496
1693
|
}
|
|
1497
1694
|
|
|
@@ -1502,6 +1699,12 @@ function workflowRetryInstanceId(runId: string, attempt: number): string {
|
|
|
1502
1699
|
return `${base.slice(0, maxBaseLength)}-${suffix}`;
|
|
1503
1700
|
}
|
|
1504
1701
|
|
|
1702
|
+
function normalizeWorkflowRunAttempt(value: unknown): number {
|
|
1703
|
+
return typeof value === 'number' && Number.isFinite(value)
|
|
1704
|
+
? Math.max(0, Math.floor(value))
|
|
1705
|
+
: 0;
|
|
1706
|
+
}
|
|
1707
|
+
|
|
1505
1708
|
async function restartWorkflowAfterPlatformReset(input: {
|
|
1506
1709
|
env: CoordinatorEnv;
|
|
1507
1710
|
ctx?: ExecutionContext;
|
|
@@ -1537,11 +1740,16 @@ async function restartWorkflowAfterPlatformReset(input: {
|
|
|
1537
1740
|
const retryInstanceId = workflowRetryInstanceId(input.runId, claim.attempts);
|
|
1538
1741
|
const retryStartedAt = Date.now();
|
|
1539
1742
|
let retryInstance: WorkflowInstance | null = null;
|
|
1743
|
+
const retryParams = { ...claim.params, runAttempt: claim.attempts };
|
|
1540
1744
|
try {
|
|
1541
1745
|
retryInstance = await createDynamicWorkflowInstance({
|
|
1542
1746
|
env: input.env,
|
|
1543
1747
|
id: retryInstanceId,
|
|
1544
|
-
params:
|
|
1748
|
+
params: workflowCreateParams(retryParams, {
|
|
1749
|
+
params: retryParams,
|
|
1750
|
+
paramsRef: claim.paramsRef,
|
|
1751
|
+
}),
|
|
1752
|
+
metadataParams: retryParams,
|
|
1545
1753
|
});
|
|
1546
1754
|
await recordWorkflowInstanceId({
|
|
1547
1755
|
env: input.env,
|
|
@@ -1591,10 +1799,14 @@ async function mintChildWorkflowExecutorToken(input: {
|
|
|
1591
1799
|
maxCreditsPerRun?: number | null;
|
|
1592
1800
|
}): Promise<string> {
|
|
1593
1801
|
const response = await input.env.HARNESS.runtimeApiCall({
|
|
1802
|
+
contract: PLAY_RUNTIME_CONTRACT,
|
|
1594
1803
|
executorToken: input.parentExecutorToken,
|
|
1595
1804
|
baseUrl: input.baseUrl,
|
|
1596
|
-
path:
|
|
1597
|
-
headers: {
|
|
1805
|
+
path: PLAY_RUNTIME_CHILD_EXECUTOR_TOKEN_COMPAT_PATH,
|
|
1806
|
+
headers: {
|
|
1807
|
+
'x-deepline-request-id': crypto.randomUUID(),
|
|
1808
|
+
[PLAY_RUNTIME_CONTRACT_HEADER]: String(PLAY_RUNTIME_CONTRACT),
|
|
1809
|
+
},
|
|
1598
1810
|
timeoutMs: 15_000,
|
|
1599
1811
|
body: {
|
|
1600
1812
|
parentRunId: input.parentRunId,
|
|
@@ -1703,10 +1915,14 @@ async function createChildRuntimeDbSession(input: {
|
|
|
1703
1915
|
}): Promise<CreateDbSessionResponse> {
|
|
1704
1916
|
const decryptionKey = await generateDbSessionPostgresUrlDecryptionKey();
|
|
1705
1917
|
const response = await input.env.HARNESS.runtimeApiCall({
|
|
1918
|
+
contract: PLAY_RUNTIME_CONTRACT,
|
|
1706
1919
|
executorToken: input.childExecutorToken,
|
|
1707
1920
|
baseUrl: input.baseUrl,
|
|
1708
|
-
path:
|
|
1709
|
-
headers: {
|
|
1921
|
+
path: PLAY_RUNTIME_API_COMPAT_PATH,
|
|
1922
|
+
headers: {
|
|
1923
|
+
'x-deepline-request-id': crypto.randomUUID(),
|
|
1924
|
+
[PLAY_RUNTIME_CONTRACT_HEADER]: String(PLAY_RUNTIME_CONTRACT),
|
|
1925
|
+
},
|
|
1710
1926
|
timeoutMs: 15_000,
|
|
1711
1927
|
body: {
|
|
1712
1928
|
action: 'create_db_session',
|
|
@@ -1812,10 +2028,14 @@ async function registerChildRunWithRuntime(input: {
|
|
|
1812
2028
|
executionProfile: string;
|
|
1813
2029
|
}): Promise<void> {
|
|
1814
2030
|
const response = await input.env.HARNESS.runtimeApiCall({
|
|
2031
|
+
contract: PLAY_RUNTIME_CONTRACT,
|
|
1815
2032
|
executorToken: input.childExecutorToken,
|
|
1816
2033
|
baseUrl: input.baseUrl,
|
|
1817
|
-
path:
|
|
1818
|
-
headers: {
|
|
2034
|
+
path: PLAY_RUNTIME_API_COMPAT_PATH,
|
|
2035
|
+
headers: {
|
|
2036
|
+
'x-deepline-request-id': crypto.randomUUID(),
|
|
2037
|
+
[PLAY_RUNTIME_CONTRACT_HEADER]: String(PLAY_RUNTIME_CONTRACT),
|
|
2038
|
+
},
|
|
1819
2039
|
timeoutMs: 15_000,
|
|
1820
2040
|
body: {
|
|
1821
2041
|
action: 'start_inline_child_run',
|
|
@@ -1858,10 +2078,14 @@ async function markRegisteredChildRunFailed(input: {
|
|
|
1858
2078
|
const message =
|
|
1859
2079
|
input.error instanceof Error ? input.error.message : String(input.error);
|
|
1860
2080
|
const response = await input.env.HARNESS.runtimeApiCall({
|
|
2081
|
+
contract: PLAY_RUNTIME_CONTRACT,
|
|
1861
2082
|
executorToken: input.childExecutorToken,
|
|
1862
2083
|
baseUrl: input.baseUrl,
|
|
1863
|
-
path:
|
|
1864
|
-
headers: {
|
|
2084
|
+
path: PLAY_RUNTIME_API_COMPAT_PATH,
|
|
2085
|
+
headers: {
|
|
2086
|
+
'x-deepline-request-id': crypto.randomUUID(),
|
|
2087
|
+
[PLAY_RUNTIME_CONTRACT_HEADER]: String(PLAY_RUNTIME_CONTRACT),
|
|
2088
|
+
},
|
|
1865
2089
|
timeoutMs: 15_000,
|
|
1866
2090
|
body: {
|
|
1867
2091
|
action: 'append_run_events',
|
|
@@ -1885,6 +2109,55 @@ async function markRegisteredChildRunFailed(input: {
|
|
|
1885
2109
|
}
|
|
1886
2110
|
}
|
|
1887
2111
|
|
|
2112
|
+
async function appendRegisteredChildRunTerminal(input: {
|
|
2113
|
+
env: CoordinatorEnv;
|
|
2114
|
+
baseUrl: string;
|
|
2115
|
+
childExecutorToken: string;
|
|
2116
|
+
childRunId: string;
|
|
2117
|
+
status: 'completed' | 'failed';
|
|
2118
|
+
result?: unknown;
|
|
2119
|
+
error?: string | null;
|
|
2120
|
+
}): Promise<void> {
|
|
2121
|
+
const event =
|
|
2122
|
+
input.status === 'completed'
|
|
2123
|
+
? ({
|
|
2124
|
+
type: 'run.completed',
|
|
2125
|
+
runId: input.childRunId,
|
|
2126
|
+
source: 'worker',
|
|
2127
|
+
occurredAt: Date.now(),
|
|
2128
|
+
...(input.result !== undefined ? { result: input.result } : {}),
|
|
2129
|
+
} satisfies PlayRunLedgerEvent)
|
|
2130
|
+
: ({
|
|
2131
|
+
type: 'run.failed',
|
|
2132
|
+
runId: input.childRunId,
|
|
2133
|
+
source: 'worker',
|
|
2134
|
+
occurredAt: Date.now(),
|
|
2135
|
+
error: input.error ?? 'Inline child Worker failed.',
|
|
2136
|
+
} satisfies PlayRunLedgerEvent);
|
|
2137
|
+
const response = await input.env.HARNESS.runtimeApiCall({
|
|
2138
|
+
contract: PLAY_RUNTIME_CONTRACT,
|
|
2139
|
+
executorToken: input.childExecutorToken,
|
|
2140
|
+
baseUrl: input.baseUrl,
|
|
2141
|
+
path: PLAY_RUNTIME_API_COMPAT_PATH,
|
|
2142
|
+
headers: {
|
|
2143
|
+
'x-deepline-request-id': crypto.randomUUID(),
|
|
2144
|
+
[PLAY_RUNTIME_CONTRACT_HEADER]: String(PLAY_RUNTIME_CONTRACT),
|
|
2145
|
+
},
|
|
2146
|
+
timeoutMs: 15_000,
|
|
2147
|
+
body: {
|
|
2148
|
+
action: 'append_run_events',
|
|
2149
|
+
playId: input.childRunId,
|
|
2150
|
+
events: [event],
|
|
2151
|
+
},
|
|
2152
|
+
});
|
|
2153
|
+
if (response.status < 200 || response.status >= 300) {
|
|
2154
|
+
const text = response.body ?? '';
|
|
2155
|
+
throw new Error(
|
|
2156
|
+
`Inline child terminal append failed ${response.status}: ${text.slice(0, 800)}`,
|
|
2157
|
+
);
|
|
2158
|
+
}
|
|
2159
|
+
}
|
|
2160
|
+
|
|
1888
2161
|
type CoordinatorRuntimeApiTiming = {
|
|
1889
2162
|
phase: string;
|
|
1890
2163
|
ms: number;
|
|
@@ -1924,12 +2197,14 @@ async function callRuntimeApiFromCoordinator(input: {
|
|
|
1924
2197
|
|
|
1925
2198
|
const fetchStartedAt = Date.now();
|
|
1926
2199
|
const response = await input.env.HARNESS.runtimeApiCall({
|
|
2200
|
+
contract: PLAY_RUNTIME_CONTRACT,
|
|
1927
2201
|
executorToken: input.executorToken,
|
|
1928
2202
|
baseUrl: input.baseUrl,
|
|
1929
|
-
path:
|
|
2203
|
+
path: PLAY_RUNTIME_API_COMPAT_PATH,
|
|
1930
2204
|
body,
|
|
1931
2205
|
headers: {
|
|
1932
2206
|
'x-deepline-request-id': crypto.randomUUID(),
|
|
2207
|
+
[PLAY_RUNTIME_CONTRACT_HEADER]: String(PLAY_RUNTIME_CONTRACT),
|
|
1933
2208
|
},
|
|
1934
2209
|
});
|
|
1935
2210
|
recordTiming('coordinator.runtime_api.fetch', fetchStartedAt);
|
|
@@ -2022,19 +2297,38 @@ async function prepareInlineChildRunWithRuntime(input: {
|
|
|
2022
2297
|
};
|
|
2023
2298
|
}
|
|
2024
2299
|
|
|
2025
|
-
function buildChildRunId(
|
|
2026
|
-
|
|
2027
|
-
|
|
2028
|
-
|
|
2029
|
-
|
|
2030
|
-
|
|
2031
|
-
|
|
2032
|
-
|
|
2033
|
-
|
|
2034
|
-
|
|
2035
|
-
|
|
2036
|
-
|
|
2037
|
-
|
|
2300
|
+
function buildChildRunId(input: {
|
|
2301
|
+
playName: string;
|
|
2302
|
+
parentRunId: string;
|
|
2303
|
+
body: Record<string, unknown>;
|
|
2304
|
+
}): string {
|
|
2305
|
+
const { playName, parentRunId, body } = input;
|
|
2306
|
+
const governance = isRecord(body.internalRunPlay)
|
|
2307
|
+
? body.internalRunPlay
|
|
2308
|
+
: null;
|
|
2309
|
+
// Adapt the coordinator's on-the-wire child-submit body to the shared
|
|
2310
|
+
// derivation. Output stays byte-identical to the previous inline
|
|
2311
|
+
// implementation (same fields → same digest → same run id), so child-submit
|
|
2312
|
+
// idempotency is preserved. See shared_libs/play-runtime/child-run-id.ts.
|
|
2313
|
+
return buildSharedChildRunId({
|
|
2314
|
+
childPlayName: playName,
|
|
2315
|
+
parentRunId,
|
|
2316
|
+
explicitIdempotencyKey:
|
|
2317
|
+
typeof body.childIdempotencyKey === 'string'
|
|
2318
|
+
? body.childIdempotencyKey
|
|
2319
|
+
: null,
|
|
2320
|
+
parentPlayName:
|
|
2321
|
+
typeof governance?.parentPlayName === 'string'
|
|
2322
|
+
? governance.parentPlayName
|
|
2323
|
+
: null,
|
|
2324
|
+
key: typeof governance?.key === 'string' ? governance.key : null,
|
|
2325
|
+
input: isRecord(body.input) ? body.input : {},
|
|
2326
|
+
graphHash: isRecord(body.manifest)
|
|
2327
|
+
? typeof body.manifest.graphHash === 'string'
|
|
2328
|
+
? body.manifest.graphHash
|
|
2329
|
+
: null
|
|
2330
|
+
: null,
|
|
2331
|
+
});
|
|
2038
2332
|
}
|
|
2039
2333
|
|
|
2040
2334
|
function normalizeRuntimeBaseUrl(value: unknown): string | null {
|
|
@@ -2087,8 +2381,7 @@ function validateChildSubmitBody(input: {
|
|
|
2087
2381
|
const { parentRunId, body } = input;
|
|
2088
2382
|
const manifest = body.manifest as PlayRuntimeManifest | undefined;
|
|
2089
2383
|
const governance = body.internalRunPlay as
|
|
2090
|
-
|
|
|
2091
|
-
| undefined;
|
|
2384
|
+
PlayCallGovernanceSnapshot | undefined;
|
|
2092
2385
|
const childPlayName =
|
|
2093
2386
|
typeof body.name === 'string' && body.name.trim()
|
|
2094
2387
|
? body.name.trim()
|
|
@@ -2219,6 +2512,7 @@ function buildChildWorkflowParams(input: {
|
|
|
2219
2512
|
executorToken: childToken,
|
|
2220
2513
|
baseUrl,
|
|
2221
2514
|
integrationMode: normalizeIntegrationMode(body.integrationMode),
|
|
2515
|
+
force: body.force === true || body.forceToolRefresh === true,
|
|
2222
2516
|
forceToolRefresh: body.forceToolRefresh === true,
|
|
2223
2517
|
orgId,
|
|
2224
2518
|
userEmail: typeof body.userEmail === 'string' ? body.userEmail : '',
|
|
@@ -2253,6 +2547,7 @@ function runRequestFromPlayWorkflowParams(
|
|
|
2253
2547
|
graphHash: params.graphHash,
|
|
2254
2548
|
userEmail: params.userEmail,
|
|
2255
2549
|
runtimeInput: params.input,
|
|
2550
|
+
runAttempt: normalizeWorkflowRunAttempt(params.runAttempt),
|
|
2256
2551
|
inlineCsv: params.inlineCsv ?? null,
|
|
2257
2552
|
inputFiles:
|
|
2258
2553
|
inputStorageKey && inputFileName
|
|
@@ -2280,8 +2575,11 @@ function runRequestFromPlayWorkflowParams(
|
|
|
2280
2575
|
executionPlan: params.executionPlan ?? null,
|
|
2281
2576
|
childPlayManifests: params.childPlayManifests ?? null,
|
|
2282
2577
|
playCallGovernance: params.playCallGovernance ?? null,
|
|
2283
|
-
force: params.forceToolRefresh === true,
|
|
2578
|
+
force: params.force === true || params.forceToolRefresh === true,
|
|
2579
|
+
forceToolRefresh: params.forceToolRefresh === true,
|
|
2284
2580
|
preloadedDbSessions: params.preloadedDbSessions ?? null,
|
|
2581
|
+
runtimeTestFaultHeader: params.runtimeTestFaultHeader ?? null,
|
|
2582
|
+
testPolicyOverrides: params.testPolicyOverrides ?? null,
|
|
2285
2583
|
inlineChildRunRegistered:
|
|
2286
2584
|
params.runtimeBackend === 'cf_workflows_dynamic_worker_inline_child',
|
|
2287
2585
|
coordinatorUrl: params.coordinatorUrl ?? null,
|
|
@@ -2376,7 +2674,11 @@ async function executeChildInline(input: {
|
|
|
2376
2674
|
}
|
|
2377
2675
|
const { manifest, governance, childPlayName, orgId, parentExecutorToken } =
|
|
2378
2676
|
validated;
|
|
2379
|
-
const childRunId = buildChildRunId(
|
|
2677
|
+
const childRunId = buildChildRunId({
|
|
2678
|
+
playName: childPlayName,
|
|
2679
|
+
parentRunId: input.parentRunId,
|
|
2680
|
+
body: input.body,
|
|
2681
|
+
});
|
|
2380
2682
|
const timings: CoordinatorTiming[] = [];
|
|
2381
2683
|
const trace = (
|
|
2382
2684
|
phase: string,
|
|
@@ -2433,10 +2735,11 @@ async function executeChildInline(input: {
|
|
|
2433
2735
|
input.body.parentPlayName.trim()
|
|
2434
2736
|
? input.body.parentPlayName.trim()
|
|
2435
2737
|
: governance.parentPlayName;
|
|
2738
|
+
const baseUrl = resolveRuntimeBaseUrl(input.env, input.body);
|
|
2436
2739
|
const { childToken, preloadedDbSessions, prepareTimings, transportTimings } =
|
|
2437
2740
|
await prepareInlineChildRunWithRuntime({
|
|
2438
2741
|
env: input.env,
|
|
2439
|
-
baseUrl
|
|
2742
|
+
baseUrl,
|
|
2440
2743
|
parentExecutorToken,
|
|
2441
2744
|
parentRunId: input.parentRunId,
|
|
2442
2745
|
parentPlayName,
|
|
@@ -2607,6 +2910,20 @@ async function executeChildInline(input: {
|
|
|
2607
2910
|
error: error.message,
|
|
2608
2911
|
},
|
|
2609
2912
|
});
|
|
2913
|
+
const terminalAppendStartedAt = Date.now();
|
|
2914
|
+
await appendRegisteredChildRunTerminal({
|
|
2915
|
+
env: input.env,
|
|
2916
|
+
baseUrl,
|
|
2917
|
+
childExecutorToken: childToken,
|
|
2918
|
+
childRunId,
|
|
2919
|
+
status: 'failed',
|
|
2920
|
+
error: error.message,
|
|
2921
|
+
});
|
|
2922
|
+
trace(
|
|
2923
|
+
'coordinator.inline_child_terminal_ledger_append',
|
|
2924
|
+
terminalAppendStartedAt,
|
|
2925
|
+
{ status: 'failed' },
|
|
2926
|
+
);
|
|
2610
2927
|
return {
|
|
2611
2928
|
workflowId: childRunId,
|
|
2612
2929
|
runId: childRunId,
|
|
@@ -2629,6 +2946,20 @@ async function executeChildInline(input: {
|
|
|
2629
2946
|
mode: 'inline_dynamic_worker',
|
|
2630
2947
|
},
|
|
2631
2948
|
});
|
|
2949
|
+
const terminalAppendStartedAt = Date.now();
|
|
2950
|
+
await appendRegisteredChildRunTerminal({
|
|
2951
|
+
env: input.env,
|
|
2952
|
+
baseUrl,
|
|
2953
|
+
childExecutorToken: childToken,
|
|
2954
|
+
childRunId,
|
|
2955
|
+
status: 'completed',
|
|
2956
|
+
result: parsed.result,
|
|
2957
|
+
});
|
|
2958
|
+
trace(
|
|
2959
|
+
'coordinator.inline_child_terminal_ledger_append',
|
|
2960
|
+
terminalAppendStartedAt,
|
|
2961
|
+
{ status: 'completed' },
|
|
2962
|
+
);
|
|
2632
2963
|
return {
|
|
2633
2964
|
workflowId: childRunId,
|
|
2634
2965
|
runId: childRunId,
|
|
@@ -2645,6 +2976,35 @@ async function executeChildInline(input: {
|
|
|
2645
2976
|
}
|
|
2646
2977
|
}
|
|
2647
2978
|
|
|
2979
|
+
function isRetryableChildWorkflowSubmitError(error: unknown): boolean {
|
|
2980
|
+
const message = error instanceof Error ? error.message : String(error);
|
|
2981
|
+
return /timed out|timeout|fetch failed|ECONNRESET|ECONNREFUSED|UND_ERR_CONNECT_TIMEOUT|internal error/i.test(
|
|
2982
|
+
message,
|
|
2983
|
+
);
|
|
2984
|
+
}
|
|
2985
|
+
|
|
2986
|
+
function isRetryableChildWorkflowSubmitResponse(
|
|
2987
|
+
status: number,
|
|
2988
|
+
body: string,
|
|
2989
|
+
): boolean {
|
|
2990
|
+
if (
|
|
2991
|
+
status === 408 ||
|
|
2992
|
+
status === 429 ||
|
|
2993
|
+
status === 502 ||
|
|
2994
|
+
status === 503 ||
|
|
2995
|
+
status === 504 ||
|
|
2996
|
+
status === 530
|
|
2997
|
+
) {
|
|
2998
|
+
return true;
|
|
2999
|
+
}
|
|
3000
|
+
return (
|
|
3001
|
+
status === 500 &&
|
|
3002
|
+
/COORDINATOR_WORKFLOW_ROUTE_FAILED|timeout exceeded when trying to connect|timed out|fetch failed|ECONNRESET|UND_ERR_CONNECT_TIMEOUT|internal error/i.test(
|
|
3003
|
+
body,
|
|
3004
|
+
)
|
|
3005
|
+
);
|
|
3006
|
+
}
|
|
3007
|
+
|
|
2648
3008
|
async function submitChildWorkflowThroughCoordinator(input: {
|
|
2649
3009
|
env: CoordinatorEnv;
|
|
2650
3010
|
parentRunId: string;
|
|
@@ -2700,7 +3060,11 @@ async function submitChildWorkflowThroughCoordinator(input: {
|
|
|
2700
3060
|
}
|
|
2701
3061
|
const { manifest, governance, childPlayName, orgId, parentExecutorToken } =
|
|
2702
3062
|
validated;
|
|
2703
|
-
const childRunId = buildChildRunId(
|
|
3063
|
+
const childRunId = buildChildRunId({
|
|
3064
|
+
playName: childPlayName,
|
|
3065
|
+
parentRunId: input.parentRunId,
|
|
3066
|
+
body: input.body,
|
|
3067
|
+
});
|
|
2704
3068
|
const baseUrl = resolveRuntimeBaseUrl(input.env, input.body);
|
|
2705
3069
|
|
|
2706
3070
|
const tokenStartedAt = Date.now();
|
|
@@ -2783,38 +3147,96 @@ async function submitChildWorkflowThroughCoordinator(input: {
|
|
|
2783
3147
|
);
|
|
2784
3148
|
|
|
2785
3149
|
const workflowSubmitStartedAt = Date.now();
|
|
2786
|
-
let response: Response;
|
|
2787
|
-
|
|
2788
|
-
|
|
2789
|
-
|
|
2790
|
-
|
|
2791
|
-
|
|
2792
|
-
|
|
2793
|
-
|
|
2794
|
-
|
|
3150
|
+
let response: Response | null = null;
|
|
3151
|
+
let responseText = '';
|
|
3152
|
+
let lastSubmitError: unknown = null;
|
|
3153
|
+
for (
|
|
3154
|
+
let attempt = 0;
|
|
3155
|
+
attempt <= CHILD_WORKFLOW_SUBMIT_RETRY_DELAYS_MS.length;
|
|
3156
|
+
attempt += 1
|
|
3157
|
+
) {
|
|
3158
|
+
try {
|
|
3159
|
+
response = await handleWorkflowRoute({
|
|
3160
|
+
runId: childRunId,
|
|
3161
|
+
action: 'submit',
|
|
3162
|
+
request: new Request(
|
|
3163
|
+
`https://deepline.coordinator.internal/workflow/${encodeURIComponent(
|
|
3164
|
+
childRunId,
|
|
3165
|
+
)}/submit`,
|
|
3166
|
+
{
|
|
3167
|
+
method: 'POST',
|
|
3168
|
+
headers: { 'content-type': 'application/json' },
|
|
3169
|
+
body: JSON.stringify(params),
|
|
3170
|
+
},
|
|
3171
|
+
),
|
|
3172
|
+
env: input.env,
|
|
3173
|
+
});
|
|
3174
|
+
} catch (error) {
|
|
3175
|
+
lastSubmitError = error;
|
|
3176
|
+
trace(
|
|
3177
|
+
'coordinator.child_submit_workflow_attempt',
|
|
3178
|
+
workflowSubmitStartedAt,
|
|
3179
|
+
manifest.graphHash,
|
|
2795
3180
|
{
|
|
2796
|
-
|
|
2797
|
-
|
|
2798
|
-
|
|
3181
|
+
childRunId,
|
|
3182
|
+
attempt: attempt + 1,
|
|
3183
|
+
status: 'threw',
|
|
3184
|
+
error: error instanceof Error ? error.message : String(error),
|
|
2799
3185
|
},
|
|
2800
|
-
)
|
|
2801
|
-
|
|
2802
|
-
|
|
2803
|
-
|
|
2804
|
-
|
|
2805
|
-
|
|
2806
|
-
|
|
2807
|
-
|
|
2808
|
-
|
|
2809
|
-
|
|
2810
|
-
|
|
2811
|
-
|
|
3186
|
+
);
|
|
3187
|
+
if (
|
|
3188
|
+
attempt >= CHILD_WORKFLOW_SUBMIT_RETRY_DELAYS_MS.length ||
|
|
3189
|
+
!isRetryableChildWorkflowSubmitError(error)
|
|
3190
|
+
) {
|
|
3191
|
+
await markRegisteredChildRunFailed({
|
|
3192
|
+
env: input.env,
|
|
3193
|
+
baseUrl,
|
|
3194
|
+
childExecutorToken: childToken,
|
|
3195
|
+
childRunId,
|
|
3196
|
+
error,
|
|
3197
|
+
}).catch((markError) => {
|
|
3198
|
+
console.error(
|
|
3199
|
+
'[coordinator] child workflow submit failure mark failed',
|
|
3200
|
+
{
|
|
3201
|
+
childRunId,
|
|
3202
|
+
error:
|
|
3203
|
+
markError instanceof Error
|
|
3204
|
+
? markError.message
|
|
3205
|
+
: String(markError),
|
|
3206
|
+
},
|
|
3207
|
+
);
|
|
3208
|
+
});
|
|
3209
|
+
throw error;
|
|
3210
|
+
}
|
|
3211
|
+
await sleep(CHILD_WORKFLOW_SUBMIT_RETRY_DELAYS_MS[attempt] ?? 0);
|
|
3212
|
+
continue;
|
|
3213
|
+
}
|
|
3214
|
+
|
|
3215
|
+
responseText = await response.text().catch(() => '');
|
|
3216
|
+
trace(
|
|
3217
|
+
'coordinator.child_submit_workflow_attempt',
|
|
3218
|
+
workflowSubmitStartedAt,
|
|
3219
|
+
manifest.graphHash,
|
|
3220
|
+
{
|
|
2812
3221
|
childRunId,
|
|
2813
|
-
|
|
2814
|
-
|
|
2815
|
-
}
|
|
2816
|
-
|
|
2817
|
-
|
|
3222
|
+
attempt: attempt + 1,
|
|
3223
|
+
status: response.status,
|
|
3224
|
+
},
|
|
3225
|
+
);
|
|
3226
|
+
if (
|
|
3227
|
+
response.ok ||
|
|
3228
|
+
attempt >= CHILD_WORKFLOW_SUBMIT_RETRY_DELAYS_MS.length ||
|
|
3229
|
+
!isRetryableChildWorkflowSubmitResponse(response.status, responseText)
|
|
3230
|
+
) {
|
|
3231
|
+
break;
|
|
3232
|
+
}
|
|
3233
|
+
lastSubmitError = `workflow submit returned ${response.status}: ${responseText.slice(0, 800)}`;
|
|
3234
|
+
await sleep(CHILD_WORKFLOW_SUBMIT_RETRY_DELAYS_MS[attempt] ?? 0);
|
|
3235
|
+
}
|
|
3236
|
+
if (!response) {
|
|
3237
|
+
throw lastSubmitError instanceof Error
|
|
3238
|
+
? lastSubmitError
|
|
3239
|
+
: new Error(String(lastSubmitError));
|
|
2818
3240
|
}
|
|
2819
3241
|
trace(
|
|
2820
3242
|
'coordinator.child_submit_workflow',
|
|
@@ -2822,7 +3244,6 @@ async function submitChildWorkflowThroughCoordinator(input: {
|
|
|
2822
3244
|
manifest.graphHash,
|
|
2823
3245
|
{ childRunId, status: response.status },
|
|
2824
3246
|
);
|
|
2825
|
-
const responseText = await response.text().catch(() => '');
|
|
2826
3247
|
if (!response.ok) {
|
|
2827
3248
|
await markRegisteredChildRunFailed({
|
|
2828
3249
|
env: input.env,
|
|
@@ -3156,6 +3577,11 @@ export class DynamicWorkflow extends WorkflowEntrypoint<
|
|
|
3156
3577
|
});
|
|
3157
3578
|
}
|
|
3158
3579
|
let dispatchedEvent = event;
|
|
3580
|
+
dispatchedEvent = await hydrateWorkflowLaunchParams({
|
|
3581
|
+
env: this.env,
|
|
3582
|
+
event: dispatchedEvent,
|
|
3583
|
+
trace,
|
|
3584
|
+
});
|
|
3159
3585
|
try {
|
|
3160
3586
|
dispatchedEvent = await hydrateWorkflowDbSessions({
|
|
3161
3587
|
env: this.env,
|
|
@@ -3202,8 +3628,8 @@ export class DynamicWorkflow extends WorkflowEntrypoint<
|
|
|
3202
3628
|
await writeCoordinatorTerminalState(this.env, {
|
|
3203
3629
|
runId: entryTrace.runId,
|
|
3204
3630
|
status: 'failed',
|
|
3205
|
-
error:
|
|
3206
|
-
.message,
|
|
3631
|
+
error:
|
|
3632
|
+
normalizeCoordinatorWorkflowRuntimeFailure(hydrateError).message,
|
|
3207
3633
|
}).catch(() => undefined);
|
|
3208
3634
|
}
|
|
3209
3635
|
}
|
|
@@ -3300,12 +3726,42 @@ export class DynamicWorkflow extends WorkflowEntrypoint<
|
|
|
3300
3726
|
}
|
|
3301
3727
|
).run(innerEvent, innerStep);
|
|
3302
3728
|
const output = isRecord(result) ? result : null;
|
|
3729
|
+
const terminalResult = output?.result ?? result;
|
|
3303
3730
|
const terminalStartedAt = Date.now();
|
|
3731
|
+
const childTerminalStartedAt = Date.now();
|
|
3732
|
+
try {
|
|
3733
|
+
const childTerminalPersisted =
|
|
3734
|
+
await appendWorkflowChildCompletedRunEvent({
|
|
3735
|
+
env,
|
|
3736
|
+
event: innerEvent,
|
|
3737
|
+
result: terminalResult,
|
|
3738
|
+
});
|
|
3739
|
+
if (childTerminalPersisted) {
|
|
3740
|
+
trace({
|
|
3741
|
+
runId: runIdForTrace,
|
|
3742
|
+
phase:
|
|
3743
|
+
'coordinator.child_terminal_ledger_append_completed',
|
|
3744
|
+
ms: Date.now() - childTerminalStartedAt,
|
|
3745
|
+
graphHash,
|
|
3746
|
+
});
|
|
3747
|
+
}
|
|
3748
|
+
} catch (childTerminalError) {
|
|
3749
|
+
console.warn(
|
|
3750
|
+
'[coordinator] child terminal ledger append failed; preserving coordinator terminal cache',
|
|
3751
|
+
{
|
|
3752
|
+
runId: runIdForTrace,
|
|
3753
|
+
message:
|
|
3754
|
+
childTerminalError instanceof Error
|
|
3755
|
+
? childTerminalError.message
|
|
3756
|
+
: String(childTerminalError),
|
|
3757
|
+
},
|
|
3758
|
+
);
|
|
3759
|
+
}
|
|
3304
3760
|
try {
|
|
3305
3761
|
await writeCoordinatorTerminalState(env, {
|
|
3306
3762
|
runId: runIdForTrace,
|
|
3307
3763
|
status: 'completed',
|
|
3308
|
-
result:
|
|
3764
|
+
result: terminalResult,
|
|
3309
3765
|
totalRows: output?.totalRows ?? output?.outputRows ?? null,
|
|
3310
3766
|
durationMs: output?.durationMs ?? null,
|
|
3311
3767
|
playName:
|
|
@@ -3586,6 +4042,69 @@ async function coordinatorRouteFetch(
|
|
|
3586
4042
|
});
|
|
3587
4043
|
}
|
|
3588
4044
|
}
|
|
4045
|
+
if (url.pathname === '/rate-acquire') {
|
|
4046
|
+
const authError = authorizeCoordinatorControlRequest({ request, env });
|
|
4047
|
+
if (authError) return authError;
|
|
4048
|
+
try {
|
|
4049
|
+
const body = (await request.json().catch(() => null)) as {
|
|
4050
|
+
bucketId?: unknown;
|
|
4051
|
+
rules?: unknown;
|
|
4052
|
+
requested?: unknown;
|
|
4053
|
+
} | null;
|
|
4054
|
+
const bucketId = typeof body?.bucketId === 'string' ? body.bucketId : '';
|
|
4055
|
+
if (!bucketId.trim()) {
|
|
4056
|
+
return Response.json(
|
|
4057
|
+
{ error: 'bucketId is required.' },
|
|
4058
|
+
{ status: 400 },
|
|
4059
|
+
);
|
|
4060
|
+
}
|
|
4061
|
+
const result = await callRateBucketControl<{
|
|
4062
|
+
granted: number;
|
|
4063
|
+
waitMs: number;
|
|
4064
|
+
}>(env, bucketId, '/rate-acquire', body);
|
|
4065
|
+
return Response.json(result);
|
|
4066
|
+
} catch (error) {
|
|
4067
|
+
return coordinatorRouteErrorResponse({
|
|
4068
|
+
logTag: '[coordinator.rate_acquire.error]',
|
|
4069
|
+
code: 'COORDINATOR_RATE_ROUTE_FAILED',
|
|
4070
|
+
phase: 'coordinator.rate.acquire',
|
|
4071
|
+
runId: null,
|
|
4072
|
+
error,
|
|
4073
|
+
});
|
|
4074
|
+
}
|
|
4075
|
+
}
|
|
4076
|
+
if (url.pathname === '/rate-penalize') {
|
|
4077
|
+
const authError = authorizeCoordinatorControlRequest({ request, env });
|
|
4078
|
+
if (authError) return authError;
|
|
4079
|
+
try {
|
|
4080
|
+
const body = (await request.json().catch(() => null)) as {
|
|
4081
|
+
bucketId?: unknown;
|
|
4082
|
+
cooldownMs?: unknown;
|
|
4083
|
+
} | null;
|
|
4084
|
+
const bucketId = typeof body?.bucketId === 'string' ? body.bucketId : '';
|
|
4085
|
+
if (!bucketId.trim()) {
|
|
4086
|
+
return Response.json(
|
|
4087
|
+
{ error: 'bucketId is required.' },
|
|
4088
|
+
{ status: 400 },
|
|
4089
|
+
);
|
|
4090
|
+
}
|
|
4091
|
+
await callRateBucketControl<{ ok?: unknown }>(
|
|
4092
|
+
env,
|
|
4093
|
+
bucketId,
|
|
4094
|
+
'/rate-penalize',
|
|
4095
|
+
body,
|
|
4096
|
+
);
|
|
4097
|
+
return Response.json({ ok: true });
|
|
4098
|
+
} catch (error) {
|
|
4099
|
+
return coordinatorRouteErrorResponse({
|
|
4100
|
+
logTag: '[coordinator.rate_penalize.error]',
|
|
4101
|
+
code: 'COORDINATOR_RATE_ROUTE_FAILED',
|
|
4102
|
+
phase: 'coordinator.rate.penalize',
|
|
4103
|
+
runId: null,
|
|
4104
|
+
error,
|
|
4105
|
+
});
|
|
4106
|
+
}
|
|
4107
|
+
}
|
|
3589
4108
|
// Workflow routes: /workflow/{runId}/{action}
|
|
3590
4109
|
const wfMatch = url.pathname.match(/^\/workflow\/([^/]+)(?:\/(.+))?$/);
|
|
3591
4110
|
if (wfMatch) {
|
|
@@ -3676,7 +4195,7 @@ async function flushTailRunLogs(
|
|
|
3676
4195
|
return;
|
|
3677
4196
|
}
|
|
3678
4197
|
await fetch(
|
|
3679
|
-
`${env.DEEPLINE_API_BASE_URL}
|
|
4198
|
+
`${env.DEEPLINE_API_BASE_URL}${PLAY_RUNTIME_TAIL_LOG_COMPAT_PATH}`,
|
|
3680
4199
|
{
|
|
3681
4200
|
method: 'POST',
|
|
3682
4201
|
headers: {
|
|
@@ -3779,7 +4298,10 @@ function coordinatorWorkflowRouteErrorResponse(input: {
|
|
|
3779
4298
|
action: input.action,
|
|
3780
4299
|
error: message,
|
|
3781
4300
|
});
|
|
3782
|
-
if (
|
|
4301
|
+
if (
|
|
4302
|
+
input.action === 'submit' &&
|
|
4303
|
+
isTenantStorageDegradationError(input.error)
|
|
4304
|
+
) {
|
|
3783
4305
|
// De-redact: a tenant-storage failure gets the loud, actionable
|
|
3784
4306
|
// WORKSPACE_STORAGE_NOT_READY message + repair instruction instead of the
|
|
3785
4307
|
// generic "internal error". Same contract as the runtime route.
|
|
@@ -3996,12 +4518,15 @@ async function handleWorkflowRoute(input: {
|
|
|
3996
4518
|
// logs. Log the tenant-storage classification loudly so the real
|
|
3997
4519
|
// cause (and the WORKSPACE_STORAGE_NOT_READY repair path) is visible.
|
|
3998
4520
|
if (storageNotReady) {
|
|
3999
|
-
console.error(
|
|
4000
|
-
|
|
4001
|
-
|
|
4002
|
-
|
|
4003
|
-
|
|
4004
|
-
|
|
4521
|
+
console.error(
|
|
4522
|
+
'[coordinator.harness_prewarm_postgres.storage_not_ready]',
|
|
4523
|
+
{
|
|
4524
|
+
runId: submittedRunId,
|
|
4525
|
+
playName: params.playName,
|
|
4526
|
+
code: WORKSPACE_STORAGE_NOT_READY_CODE,
|
|
4527
|
+
error: error instanceof Error ? error.message : String(error),
|
|
4528
|
+
},
|
|
4529
|
+
);
|
|
4005
4530
|
}
|
|
4006
4531
|
});
|
|
4007
4532
|
input.ctx?.waitUntil(prewarmPromise);
|
|
@@ -4010,9 +4535,12 @@ async function handleWorkflowRoute(input: {
|
|
|
4010
4535
|
params,
|
|
4011
4536
|
});
|
|
4012
4537
|
const workflowParams = dbSessionExternalization.params;
|
|
4538
|
+
workflowParams.submittedAt = Date.now();
|
|
4539
|
+
let launchState: Awaited<ReturnType<typeof persistWorkflowLaunchState>> =
|
|
4540
|
+
{};
|
|
4013
4541
|
try {
|
|
4014
4542
|
const retryStateStartedAt = Date.now();
|
|
4015
|
-
|
|
4543
|
+
launchState = await persistWorkflowLaunchState({
|
|
4016
4544
|
env,
|
|
4017
4545
|
runId: submittedRunId,
|
|
4018
4546
|
params: workflowParams,
|
|
@@ -4065,7 +4593,7 @@ async function handleWorkflowRoute(input: {
|
|
|
4065
4593
|
error,
|
|
4066
4594
|
});
|
|
4067
4595
|
}
|
|
4068
|
-
|
|
4596
|
+
const createParams = workflowCreateParams(workflowParams, launchState);
|
|
4069
4597
|
let instance: WorkflowInstance | null = null;
|
|
4070
4598
|
try {
|
|
4071
4599
|
const submitClaimStartedAt = Date.now();
|
|
@@ -4167,7 +4695,8 @@ async function handleWorkflowRoute(input: {
|
|
|
4167
4695
|
createDynamicWorkflowInstance({
|
|
4168
4696
|
env,
|
|
4169
4697
|
id: defaultInstanceId,
|
|
4170
|
-
params:
|
|
4698
|
+
params: createParams,
|
|
4699
|
+
metadataParams: workflowParams,
|
|
4171
4700
|
}),
|
|
4172
4701
|
getExisting: () => env.PLAY_WORKFLOW.get(defaultInstanceId),
|
|
4173
4702
|
onCreateFailure: async () => {
|
|
@@ -4737,7 +5266,8 @@ function stableHash(value: string): string {
|
|
|
4737
5266
|
return (hash >>> 0).toString(36);
|
|
4738
5267
|
}
|
|
4739
5268
|
|
|
4740
|
-
const DYNAMIC_PLAY_WORKER_HARNESS_VERSION =
|
|
5269
|
+
const DYNAMIC_PLAY_WORKER_HARNESS_VERSION =
|
|
5270
|
+
DYNAMIC_PLAY_WORKER_ARTIFACT_VERSION;
|
|
4741
5271
|
const DYNAMIC_WORKER_BUNDLED_CODE_CACHE_MAX_ENTRIES = 64;
|
|
4742
5272
|
const dynamicWorkerBundledCodeCache = new Map<string, string>();
|
|
4743
5273
|
|
|
@@ -5057,7 +5587,7 @@ export class TenantWorkflow extends WorkflowEntrypoint {
|
|
|
5057
5587
|
const runId = payload && typeof payload.runId === "string" ? payload.runId : "warmup";
|
|
5058
5588
|
const startedAt = Date.now();
|
|
5059
5589
|
if (this.env.RUNTIME_API) {
|
|
5060
|
-
await this.env.RUNTIME_API.fetch(new Request("https://deepline.runtime.internal
|
|
5590
|
+
await this.env.RUNTIME_API.fetch(new Request("https://deepline.runtime.internal${PLAY_RUNTIME_API_COMPAT_PATH}", {
|
|
5061
5591
|
method: "POST",
|
|
5062
5592
|
headers: { "content-type": "application/json" },
|
|
5063
5593
|
body: "{}"
|