deepline 0.1.26 → 0.1.28

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.
@@ -232,7 +232,7 @@ interface CoordinatorEnv {
232
232
  /**
233
233
  * Service binding to the long-lived Play Harness Worker
234
234
  * (apps/play-harness-worker). Provides typed RPC access to leaf-level
235
- * helpers (zod validation, runtime-API HTTP forwarder, …) that we
235
+ * helpers (runtime-API HTTP forwarder, Neon dataset IO, …) that we
236
236
  * deliberately keep OUT of every per-graphHash play bundle.
237
237
  *
238
238
  * Optional: when missing (e.g. an older deploy that hasn't been wired
@@ -547,10 +547,10 @@ const WORKFLOW_POOL_READY_POLL_MS = 250;
547
547
  const WORKFLOW_POOL_REFILL_ON_MISS_TIMEOUT_MS = 2_500;
548
548
  const WORKFLOW_POOL_REFILL_ON_MISS_MIN_AVAILABLE = 4;
549
549
  const WORKFLOW_POOL_CONTROL_TIMEOUT_MS = 750;
550
+ const WORKFLOW_POOL_START_ACK_TIMEOUT_MS = 750;
551
+ const WORKFLOW_POOL_START_ACK_POLL_MS = 25;
550
552
  const SUBMIT_INITIAL_STATE_MAX_WAIT_MS = 0;
551
553
  const SUBMIT_INITIAL_STATE_POLL_MS = 50;
552
- const WORKFLOW_POOL_DISABLED_REASON =
553
- 'Cloudflare Workflows start runs directly; waitForEvent is reserved for real durable external waits.';
554
554
  function buildDynamicWorkflowMetadata(
555
555
  params: PlayWorkflowParams,
556
556
  ): DynamicWorkflowMetadata {
@@ -623,7 +623,7 @@ function readWorkflowTraceContext(event: unknown): {
623
623
  }
624
624
 
625
625
  function workflowPoolEnabled(): boolean {
626
- return false;
626
+ return WORKFLOW_POOL_TARGET_SIZE > 0;
627
627
  }
628
628
 
629
629
  function workflowPoolTargetSize(): number {
@@ -889,8 +889,33 @@ async function mapRunToWorkflowInstance(input: {
889
889
  env: CoordinatorEnv;
890
890
  runId: string;
891
891
  instanceId: string;
892
- }): Promise<void> {
893
- await callWorkflowPool(input.env, '/pool-map-run', {
892
+ started?: boolean;
893
+ }): Promise<boolean> {
894
+ const body = await callWorkflowPool<{ mapped?: unknown }>(
895
+ input.env,
896
+ '/pool-map-run',
897
+ {
898
+ method: 'POST',
899
+ body: JSON.stringify({
900
+ runId: input.runId,
901
+ instanceId: input.instanceId,
902
+ started: input.started === true,
903
+ version: WORKFLOW_POOL_PROTOCOL_VERSION,
904
+ }),
905
+ },
906
+ );
907
+ return body.mapped !== false;
908
+ }
909
+
910
+ async function blockWorkflowPoolRun(input: {
911
+ env: CoordinatorEnv;
912
+ runId: string;
913
+ instanceId: string;
914
+ }): Promise<{ blocked: boolean; started: boolean }> {
915
+ const body = await callWorkflowPool<{
916
+ blocked?: unknown;
917
+ started?: unknown;
918
+ }>(input.env, '/pool-block-run', {
894
919
  method: 'POST',
895
920
  body: JSON.stringify({
896
921
  runId: input.runId,
@@ -898,6 +923,82 @@ async function mapRunToWorkflowInstance(input: {
898
923
  version: WORKFLOW_POOL_PROTOCOL_VERSION,
899
924
  }),
900
925
  });
926
+ return {
927
+ blocked: body.blocked === true,
928
+ started: body.started === true,
929
+ };
930
+ }
931
+
932
+ async function readWorkflowPoolRunMapping(input: {
933
+ env: CoordinatorEnv;
934
+ runId: string;
935
+ }): Promise<{ instanceId: string | null; startedAt: number | null }> {
936
+ const body = await callWorkflowPool<{
937
+ instanceId?: unknown;
938
+ startedAt?: unknown;
939
+ }>(
940
+ input.env,
941
+ `/pool-resolve-run?runId=${encodeURIComponent(input.runId)}&version=${encodeURIComponent(
942
+ WORKFLOW_POOL_PROTOCOL_VERSION,
943
+ )}`,
944
+ ).catch(() => ({ instanceId: null, startedAt: null }));
945
+ return {
946
+ instanceId:
947
+ typeof body.instanceId === 'string' && body.instanceId
948
+ ? body.instanceId
949
+ : null,
950
+ startedAt:
951
+ typeof body.startedAt === 'number' && Number.isFinite(body.startedAt)
952
+ ? body.startedAt
953
+ : null,
954
+ };
955
+ }
956
+
957
+ async function waitForWorkflowPoolStartAck(input: {
958
+ env: CoordinatorEnv;
959
+ runId: string;
960
+ instanceId: string;
961
+ timeoutMs: number;
962
+ }): Promise<{
963
+ acknowledged: boolean;
964
+ ms: number;
965
+ polls: number;
966
+ startedAt: number | null;
967
+ mappedInstanceId: string | null;
968
+ }> {
969
+ const startedAt = Date.now();
970
+ let polls = 0;
971
+ let latestMapping: { instanceId: string | null; startedAt: number | null } = {
972
+ instanceId: null,
973
+ startedAt: null,
974
+ };
975
+ while (Date.now() - startedAt < input.timeoutMs) {
976
+ polls += 1;
977
+ latestMapping = await readWorkflowPoolRunMapping({
978
+ env: input.env,
979
+ runId: input.runId,
980
+ });
981
+ if (
982
+ latestMapping.instanceId === input.instanceId &&
983
+ latestMapping.startedAt !== null
984
+ ) {
985
+ return {
986
+ acknowledged: true,
987
+ ms: Date.now() - startedAt,
988
+ polls,
989
+ startedAt: latestMapping.startedAt,
990
+ mappedInstanceId: latestMapping.instanceId,
991
+ };
992
+ }
993
+ await sleep(WORKFLOW_POOL_START_ACK_POLL_MS);
994
+ }
995
+ return {
996
+ acknowledged: false,
997
+ ms: Date.now() - startedAt,
998
+ polls,
999
+ startedAt: latestMapping.startedAt,
1000
+ mappedInstanceId: latestMapping.instanceId,
1001
+ };
901
1002
  }
902
1003
 
903
1004
  async function resolveWorkflowInstanceIdForRun(
@@ -907,15 +1008,8 @@ async function resolveWorkflowInstanceIdForRun(
907
1008
  if (!workflowPoolEnabled()) {
908
1009
  return workflowInstanceId(runId);
909
1010
  }
910
- const body = await callWorkflowPool<{ instanceId?: unknown }>(
911
- env,
912
- `/pool-resolve-run?runId=${encodeURIComponent(runId)}&version=${encodeURIComponent(
913
- WORKFLOW_POOL_PROTOCOL_VERSION,
914
- )}`,
915
- ).catch(() => ({ instanceId: null }));
916
- return typeof body.instanceId === 'string' && body.instanceId
917
- ? body.instanceId
918
- : workflowInstanceId(runId);
1011
+ const mapping = await readWorkflowPoolRunMapping({ env, runId });
1012
+ return mapping.instanceId ? mapping.instanceId : workflowInstanceId(runId);
919
1013
  }
920
1014
 
921
1015
  async function clearWorkflowPool(env: CoordinatorEnv): Promise<number> {
@@ -927,7 +1021,10 @@ async function clearWorkflowPool(env: CoordinatorEnv): Promise<number> {
927
1021
  );
928
1022
  await Promise.all(
929
1023
  entries.map(async (entry) => {
930
- const instance = await env.PLAY_WORKFLOW.get(entry.id);
1024
+ const instance = await getWorkflowPoolInstance(env, entry.id);
1025
+ if (!instance) {
1026
+ return;
1027
+ }
931
1028
  try {
932
1029
  await instance.terminate().catch(() => undefined);
933
1030
  } finally {
@@ -942,6 +1039,27 @@ function workflowStatusName(status: InstanceStatus | null): string {
942
1039
  return typeof status?.status === 'string' ? status.status : 'unknown';
943
1040
  }
944
1041
 
1042
+ function isWorkflowInstanceNotFoundError(error: unknown): boolean {
1043
+ const message = error instanceof Error ? error.message : String(error);
1044
+ return /not[ _]found|not_found|does not exist|no such instance|404/i.test(
1045
+ message,
1046
+ );
1047
+ }
1048
+
1049
+ async function getWorkflowPoolInstance(
1050
+ env: CoordinatorEnv,
1051
+ instanceId: string,
1052
+ ): Promise<WorkflowInstance | null> {
1053
+ try {
1054
+ return await env.PLAY_WORKFLOW.get(instanceId);
1055
+ } catch (error) {
1056
+ if (isWorkflowInstanceNotFoundError(error)) {
1057
+ return null;
1058
+ }
1059
+ throw error;
1060
+ }
1061
+ }
1062
+
945
1063
  function workflowPoolStatusIsReady(statusName: string): boolean {
946
1064
  // This is only a liveness guard. Readiness itself comes from the pooled
947
1065
  // Workflow calling /pool-ready after waitForEvent("play_start") has been
@@ -1024,7 +1142,11 @@ async function refillWorkflowPoolOnce(
1024
1142
  const promotedIds: string[] = [];
1025
1143
  const removedIds: string[] = [];
1026
1144
  for (const entry of warmingEntries) {
1027
- const instance = await env.PLAY_WORKFLOW.get(entry.id);
1145
+ const instance = await getWorkflowPoolInstance(env, entry.id);
1146
+ if (!instance) {
1147
+ removedIds.push(entry.id);
1148
+ continue;
1149
+ }
1028
1150
  try {
1029
1151
  if (entry.state === 'ready' && entry.readyAt !== null) {
1030
1152
  promotedIds.push(entry.id);
@@ -1251,7 +1373,21 @@ async function submitViaPooledWorkflow(input: {
1251
1373
  return null;
1252
1374
  }
1253
1375
 
1254
- const instance = await input.env.PLAY_WORKFLOW.get(pooledInstanceId);
1376
+ const instance = await getWorkflowPoolInstance(input.env, pooledInstanceId);
1377
+ if (!instance) {
1378
+ await blockWorkflowPoolRun({
1379
+ env: input.env,
1380
+ runId: input.params.runId,
1381
+ instanceId: pooledInstanceId,
1382
+ }).catch(() => undefined);
1383
+ input.recordSubmitTiming({
1384
+ phase: 'coordinator.workflow_pool_ready_check',
1385
+ ms: Date.now() - leaseStartedAt,
1386
+ graphHash: input.params.graphHash ?? null,
1387
+ extra: { instanceId: pooledInstanceId, status: 'missing' },
1388
+ });
1389
+ return null;
1390
+ }
1255
1391
  const readyCheckStartedAt = Date.now();
1256
1392
  const status = await instance.status().catch(() => null);
1257
1393
  const statusName = workflowStatusName(status);
@@ -1262,6 +1398,11 @@ async function submitViaPooledWorkflow(input: {
1262
1398
  extra: { instanceId: pooledInstanceId, status: statusName },
1263
1399
  });
1264
1400
  if (!workflowPoolStatusIsReady(statusName)) {
1401
+ await blockWorkflowPoolRun({
1402
+ env: input.env,
1403
+ runId: input.params.runId,
1404
+ instanceId: pooledInstanceId,
1405
+ }).catch(() => undefined);
1265
1406
  await instance.terminate().catch(() => undefined);
1266
1407
  disposeRpcStub(instance);
1267
1408
  return null;
@@ -1273,6 +1414,11 @@ async function submitViaPooledWorkflow(input: {
1273
1414
  payload: buildDispatcherEnvelope(input.params),
1274
1415
  });
1275
1416
  } catch (error) {
1417
+ await blockWorkflowPoolRun({
1418
+ env: input.env,
1419
+ runId: input.params.runId,
1420
+ instanceId: pooledInstanceId,
1421
+ }).catch(() => undefined);
1276
1422
  disposeRpcStub(instance);
1277
1423
  console.warn('[coordinator.workflow_pool] sendEvent failed; falling back', {
1278
1424
  runId: input.params.runId,
@@ -1287,7 +1433,63 @@ async function submitViaPooledWorkflow(input: {
1287
1433
  graphHash: input.params.graphHash ?? null,
1288
1434
  extra: { instanceId: pooledInstanceId },
1289
1435
  });
1290
- return instance;
1436
+ const ack = await waitForWorkflowPoolStartAck({
1437
+ env: input.env,
1438
+ runId: input.params.runId,
1439
+ instanceId: pooledInstanceId,
1440
+ timeoutMs: WORKFLOW_POOL_START_ACK_TIMEOUT_MS,
1441
+ });
1442
+ if (ack.acknowledged) {
1443
+ input.recordSubmitTiming({
1444
+ phase: 'coordinator.workflow_pool_start_ack',
1445
+ ms: ack.ms,
1446
+ graphHash: input.params.graphHash ?? null,
1447
+ extra: {
1448
+ acknowledged: true,
1449
+ instanceId: pooledInstanceId,
1450
+ polls: ack.polls,
1451
+ startedAt: ack.startedAt,
1452
+ },
1453
+ });
1454
+ return instance;
1455
+ }
1456
+
1457
+ const blockStartedAt = Date.now();
1458
+ const block = await blockWorkflowPoolRun({
1459
+ env: input.env,
1460
+ runId: input.params.runId,
1461
+ instanceId: pooledInstanceId,
1462
+ }).catch(() => ({ blocked: false, started: false }));
1463
+ input.recordSubmitTiming({
1464
+ phase: 'coordinator.workflow_pool_start_ack',
1465
+ ms: ack.ms,
1466
+ graphHash: input.params.graphHash ?? null,
1467
+ extra: {
1468
+ acknowledged: block.started,
1469
+ instanceId: pooledInstanceId,
1470
+ polls: ack.polls,
1471
+ startedAt: ack.startedAt,
1472
+ mappedInstanceId: ack.mappedInstanceId,
1473
+ blocked: block.blocked,
1474
+ blockMs: Date.now() - blockStartedAt,
1475
+ },
1476
+ });
1477
+ if (block.started) {
1478
+ return instance;
1479
+ }
1480
+ await instance.terminate().catch(() => undefined);
1481
+ disposeRpcStub(instance);
1482
+ input.recordSubmitTiming({
1483
+ phase: 'coordinator.workflow_pool_fallback',
1484
+ ms: Date.now() - sendStartedAt,
1485
+ graphHash: input.params.graphHash ?? null,
1486
+ extra: {
1487
+ reason: 'start_ack_timeout',
1488
+ instanceId: pooledInstanceId,
1489
+ ackTimeoutMs: WORKFLOW_POOL_START_ACK_TIMEOUT_MS,
1490
+ },
1491
+ });
1492
+ return null;
1291
1493
  }
1292
1494
 
1293
1495
  function readWorkflowPayload(event: unknown): Record<string, unknown> | null {
@@ -2186,9 +2388,35 @@ export class DynamicWorkflow extends WorkflowEntrypoint<
2186
2388
  dispatchedEvent = {
2187
2389
  payload: startEvent.payload,
2188
2390
  timestamp: startEvent.timestamp,
2189
- instanceId: workflowEvent.instanceId,
2391
+ instanceId: workflowEvent.instanceId ?? pooledPayload.poolId,
2190
2392
  };
2191
2393
  const dispatchedTrace = readWorkflowTraceContext(dispatchedEvent);
2394
+ const mapped = await mapRunToWorkflowInstance({
2395
+ env: this.env,
2396
+ runId: dispatchedTrace.runId,
2397
+ instanceId: pooledPayload.poolId,
2398
+ started: true,
2399
+ }).catch((error) => {
2400
+ console.warn('[coordinator.workflow_pool] start ack failed', {
2401
+ poolId: pooledPayload.poolId,
2402
+ runId: dispatchedTrace.runId,
2403
+ message: error instanceof Error ? error.message : String(error),
2404
+ });
2405
+ return false;
2406
+ });
2407
+ if (!mapped) {
2408
+ trace({
2409
+ runId: dispatchedTrace.runId,
2410
+ phase: 'coordinator.workflow_pool_start_blocked',
2411
+ ms: 0,
2412
+ graphHash: dispatchedTrace.graphHash,
2413
+ extra: {
2414
+ instanceId: pooledPayload.poolId,
2415
+ eventType: startEvent.type,
2416
+ },
2417
+ });
2418
+ return { ok: false, blocked: true, runId: dispatchedTrace.runId };
2419
+ }
2192
2420
  const eventDeliveryMs = Math.max(
2193
2421
  0,
2194
2422
  Date.now() - startEvent.timestamp.getTime(),
@@ -2472,7 +2700,15 @@ const coordinatorEntrypoint = {
2472
2700
  const entries = await listWorkflowPoolEntries(env);
2473
2701
  const detailed = [];
2474
2702
  for (const entry of entries) {
2475
- const instance = await env.PLAY_WORKFLOW.get(entry.id);
2703
+ const instance = await getWorkflowPoolInstance(env, entry.id);
2704
+ if (!instance) {
2705
+ detailed.push({
2706
+ ...entry,
2707
+ status: 'missing',
2708
+ mappedStatus: 'failed',
2709
+ });
2710
+ continue;
2711
+ }
2476
2712
  try {
2477
2713
  const status = await instance.status().catch(() => null);
2478
2714
  detailed.push({
@@ -2536,6 +2772,14 @@ const coordinatorEntrypoint = {
2536
2772
  async tail(events: unknown[], env: CoordinatorEnv): Promise<void> {
2537
2773
  await flushTailRunLogs(events, env);
2538
2774
  },
2775
+ async scheduled(
2776
+ _controller: unknown,
2777
+ env: CoordinatorEnv,
2778
+ ctx?: ExecutionContext,
2779
+ ): Promise<void> {
2780
+ if (!workflowPoolEnabled()) return;
2781
+ ctx?.waitUntil(refillWorkflowPool(env).catch(() => undefined));
2782
+ },
2539
2783
  };
2540
2784
 
2541
2785
  export default coordinatorEntrypoint;
@@ -2698,36 +2942,100 @@ async function handleWorkflowRoute(input: {
2698
2942
  'Start apps/play-harness-worker before the coordinator or fix wrangler.toml services.',
2699
2943
  );
2700
2944
  }
2945
+ const preloadedDbSessions = Array.isArray(params.preloadedDbSessions)
2946
+ ? params.preloadedDbSessions
2947
+ : [];
2948
+ if (preloadedDbSessions.length > 0 && params.executorToken) {
2949
+ const prewarmStartedAt = Date.now();
2950
+ recordSubmitTiming({
2951
+ phase: 'coordinator.harness_prewarm_postgres_start',
2952
+ ms: 0,
2953
+ graphHash: params.graphHash ?? null,
2954
+ extra: { sessions: preloadedDbSessions.length },
2955
+ });
2956
+ const prewarmPromise = env.HARNESS.prewarmPostgresSessions({
2957
+ executorToken: params.executorToken,
2958
+ sessions: preloadedDbSessions,
2959
+ })
2960
+ .then((result) => {
2961
+ recordSubmitTiming({
2962
+ phase: 'coordinator.harness_prewarm_postgres',
2963
+ ms: Date.now() - prewarmStartedAt,
2964
+ graphHash: params.graphHash ?? null,
2965
+ extra: {
2966
+ status: 'ok',
2967
+ sessions: result.sessions,
2968
+ },
2969
+ });
2970
+ })
2971
+ .catch((error: unknown) => {
2972
+ recordSubmitTiming({
2973
+ phase: 'coordinator.harness_prewarm_postgres',
2974
+ ms: Date.now() - prewarmStartedAt,
2975
+ graphHash: params.graphHash ?? null,
2976
+ extra: {
2977
+ status: 'failed',
2978
+ sessions: preloadedDbSessions.length,
2979
+ error: error instanceof Error ? error.message : String(error),
2980
+ },
2981
+ });
2982
+ });
2983
+ input.ctx?.waitUntil(prewarmPromise);
2984
+ }
2701
2985
  let instance: WorkflowInstance | null = null;
2702
2986
  try {
2703
- const dispatchStartedAt = Date.now();
2987
+ const statusEventStartedAt = Date.now();
2988
+ await appendCoordinatorRunEvent(env, {
2989
+ runId: submittedRunId,
2990
+ type: 'status',
2991
+ status: 'running',
2992
+ ts: Date.now(),
2993
+ });
2704
2994
  recordSubmitTiming({
2705
- phase: 'coordinator.workflow_pool_attempt',
2706
- ms: 0,
2995
+ phase: 'coordinator.submit_status_event',
2996
+ ms: Date.now() - statusEventStartedAt,
2707
2997
  graphHash: params.graphHash ?? null,
2708
- extra: {
2709
- usedPool: false,
2710
- disabled: true,
2711
- reason: WORKFLOW_POOL_DISABLED_REASON,
2712
- },
2713
2998
  });
2714
- const createStartedAt = Date.now();
2715
- instance = await createDynamicWorkflowInstance({
2999
+ const dispatchStartedAt = Date.now();
3000
+ const poolAttemptStartedAt = Date.now();
3001
+ instance = await submitViaPooledWorkflow({
2716
3002
  env,
2717
- id: defaultInstanceId,
2718
3003
  params,
3004
+ recordSubmitTiming,
2719
3005
  });
2720
3006
  recordSubmitTiming({
2721
- phase: 'coordinator.workflow_create',
2722
- ms: Date.now() - createStartedAt,
3007
+ phase: 'coordinator.workflow_pool_attempt',
3008
+ ms: Date.now() - poolAttemptStartedAt,
2723
3009
  graphHash: params.graphHash ?? null,
2724
- extra: { instanceId: instance.id },
3010
+ extra: {
3011
+ usedPool: Boolean(instance),
3012
+ enabled: workflowPoolEnabled(),
3013
+ },
2725
3014
  });
3015
+ if (!instance) {
3016
+ const createStartedAt = Date.now();
3017
+ instance = await createDynamicWorkflowInstance({
3018
+ env,
3019
+ id: defaultInstanceId,
3020
+ params,
3021
+ });
3022
+ recordSubmitTiming({
3023
+ phase: 'coordinator.workflow_create',
3024
+ ms: Date.now() - createStartedAt,
3025
+ graphHash: params.graphHash ?? null,
3026
+ extra: { instanceId: instance.id },
3027
+ });
3028
+ }
2726
3029
  recordSubmitTiming({
2727
3030
  phase: 'coordinator.dispatch_workflow',
2728
3031
  ms: Date.now() - dispatchStartedAt,
2729
3032
  graphHash: params.graphHash ?? null,
2730
- extra: { startMode: 'direct_workflow_create' },
3033
+ extra: {
3034
+ startMode:
3035
+ instance.id === defaultInstanceId
3036
+ ? 'direct_workflow_create'
3037
+ : 'pooled_workflow_start_event',
3038
+ },
2731
3039
  });
2732
3040
  const initialWaitMsRaw = Number(
2733
3041
  new URL(request.url).searchParams.get('initialWaitMs') ?? '0',
@@ -2761,6 +3069,9 @@ async function handleWorkflowRoute(input: {
2761
3069
  ms: totalMs,
2762
3070
  graphHash: params.graphHash ?? null,
2763
3071
  });
3072
+ if (workflowPoolEnabled() && instance.id === defaultInstanceId) {
3073
+ input.ctx?.waitUntil(refillWorkflowPool(env).catch(() => undefined));
3074
+ }
2764
3075
  return Response.json({
2765
3076
  runId,
2766
3077
  status: 'submitted',
@@ -3016,11 +3327,19 @@ async function handleWorkflowRoute(input: {
3016
3327
  afterSeq,
3017
3328
  timeoutMs: waitMs,
3018
3329
  }).catch(() => null);
3330
+ const rawEvents = eventResult?.events ?? [];
3331
+ const terminalEventIndex = rawEvents.findIndex(
3332
+ (event) => event.type === 'terminal',
3333
+ );
3334
+ const events =
3335
+ terminalEventIndex >= 0
3336
+ ? rawEvents.slice(0, terminalEventIndex + 1)
3337
+ : rawEvents;
3019
3338
  const coordinatorTrace =
3020
- includeTrace && eventResult?.events.length
3339
+ includeTrace && events.length
3021
3340
  ? await listCoordinatorPerfTrace(env, runId).catch(() => [])
3022
3341
  : [];
3023
- const terminalEvent = eventResult?.events.find(
3342
+ const terminalEvent = events.find(
3024
3343
  (event): event is Extract<CoordinatorRunEvent, { type: 'terminal' }> =>
3025
3344
  event.type === 'terminal',
3026
3345
  );
@@ -3036,7 +3355,7 @@ async function handleWorkflowRoute(input: {
3036
3355
  completedAt: terminalEvent.ts,
3037
3356
  liveLogs: sanitizeLiveLogLines(terminalEvent.liveLogs),
3038
3357
  liveNodeProgress: terminalEvent.liveNodeProgress ?? null,
3039
- events: eventResult?.events ?? [],
3358
+ events,
3040
3359
  latestSeq: eventResult?.latestSeq ?? afterSeq,
3041
3360
  wait: null,
3042
3361
  coordinatorObserve: {
@@ -3052,7 +3371,7 @@ async function handleWorkflowRoute(input: {
3052
3371
  return Response.json({
3053
3372
  runId,
3054
3373
  status: 'running',
3055
- events: eventResult?.events ?? [],
3374
+ events,
3056
3375
  latestSeq: eventResult?.latestSeq ?? afterSeq,
3057
3376
  wait: null,
3058
3377
  coordinatorObserve: {
@@ -3250,7 +3569,7 @@ function stableHash(value: string): string {
3250
3569
  return (hash >>> 0).toString(36);
3251
3570
  }
3252
3571
 
3253
- const DYNAMIC_PLAY_WORKER_HARNESS_VERSION = 'h11-full-row-dataset-handles';
3572
+ const DYNAMIC_PLAY_WORKER_HARNESS_VERSION = 'h16-coordinator-only-prewarm';
3254
3573
  const DYNAMIC_WORKER_BUNDLED_CODE_CACHE_MAX_ENTRIES = 64;
3255
3574
  const dynamicWorkerBundledCodeCache = new Map<string, string>();
3256
3575