deepline 0.1.139 → 0.1.140

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.
@@ -53,6 +53,7 @@ import {
53
53
  import {
54
54
  decideWorkflowPlatformRetry,
55
55
  PLATFORM_DEPLOY_WORKFLOW_RETRY_LIMIT,
56
+ shouldPublishWorkflowRuntimeFailure,
56
57
  } from './workflow-retry';
57
58
  import {
58
59
  WORKFLOW_RETRY_PARAMS_EXTERNALIZE_AFTER_BYTES,
@@ -274,6 +275,7 @@ interface CoordinatorEnv {
274
275
  DEEPLINE_INTERNAL_TOKEN?: string;
275
276
  DEEPLINE_TAIL_LOG_TOKEN?: string;
276
277
  DEEPLINE_COORDINATOR_DEPLOY_MARKER?: string;
278
+ CF_VERSION_METADATA?: WorkerVersionMetadata;
277
279
  VERCEL_PROTECTION_BYPASS_TOKEN?: string;
278
280
  DEEPLINE_PLAY_PREVIEW_SLUG?: string;
279
281
  /**
@@ -3038,27 +3040,44 @@ export class DynamicWorkflow extends WorkflowEntrypoint<
3038
3040
  : null,
3039
3041
  },
3040
3042
  );
3041
- await markWorkflowRuntimeFailure({
3042
- env,
3043
- event: innerEvent,
3044
- error: innerError,
3045
- }).catch((markError) => {
3046
- console.error(
3047
- '[coordinator] failed to forward DynamicWorkflow runner error',
3043
+ if (
3044
+ shouldPublishWorkflowRuntimeFailure({
3045
+ error: innerError,
3046
+ retryAttempts: 0,
3047
+ })
3048
+ ) {
3049
+ await markWorkflowRuntimeFailure({
3050
+ env,
3051
+ event: innerEvent,
3052
+ error: innerError,
3053
+ }).catch((markError) => {
3054
+ console.error(
3055
+ '[coordinator] failed to forward DynamicWorkflow runner error',
3056
+ {
3057
+ graphHash,
3058
+ message:
3059
+ markError instanceof Error
3060
+ ? markError.message
3061
+ : String(markError),
3062
+ },
3063
+ );
3064
+ });
3065
+ await writeCoordinatorTerminalState(env, {
3066
+ runId: runIdForTrace,
3067
+ status: 'failed',
3068
+ error: failure.message,
3069
+ }).catch(() => undefined);
3070
+ } else {
3071
+ console.warn(
3072
+ '[coordinator] DynamicWorkflow platform reset will be retried; not publishing durable run.failed',
3048
3073
  {
3049
3074
  graphHash,
3050
- message:
3051
- markError instanceof Error
3052
- ? markError.message
3053
- : String(markError),
3075
+ runId: runIdForTrace,
3076
+ errorCode: failure.code,
3077
+ retryLimit: PLATFORM_DEPLOY_WORKFLOW_RETRY_LIMIT,
3054
3078
  },
3055
3079
  );
3056
- });
3057
- await writeCoordinatorTerminalState(env, {
3058
- runId: runIdForTrace,
3059
- status: 'failed',
3060
- error: failure.message,
3061
- }).catch(() => undefined);
3080
+ }
3062
3081
  throw innerError;
3063
3082
  }
3064
3083
  },
@@ -3136,7 +3155,20 @@ async function coordinatorRouteFetch(
3136
3155
  ): Promise<Response> {
3137
3156
  const url = new URL(request.url);
3138
3157
  if (url.pathname === '/health') {
3139
- return new Response('ok', { status: 200 });
3158
+ const headers = new Headers();
3159
+ headers.set(
3160
+ 'x-deepline-runtime-deploy-version',
3161
+ env.CF_VERSION_METADATA?.id ??
3162
+ env.DEEPLINE_COORDINATOR_DEPLOY_MARKER ??
3163
+ '',
3164
+ );
3165
+ if (env.DEEPLINE_COORDINATOR_DEPLOY_MARKER) {
3166
+ headers.set(
3167
+ 'x-deepline-deploy-marker',
3168
+ env.DEEPLINE_COORDINATOR_DEPLOY_MARKER,
3169
+ );
3170
+ }
3171
+ return new Response('ok', { status: 200, headers });
3140
3172
  }
3141
3173
  if (url.pathname === '/warmup/submit') {
3142
3174
  const authError = authorizeCoordinatorControlRequest({ request, env });
@@ -3174,6 +3206,10 @@ async function coordinatorRouteFetch(
3174
3206
  return Response.json({
3175
3207
  ok: true,
3176
3208
  deployMarker: env.DEEPLINE_COORDINATOR_DEPLOY_MARKER ?? null,
3209
+ runtimeDeployVersion:
3210
+ env.CF_VERSION_METADATA?.id ??
3211
+ env.DEEPLINE_COORDINATOR_DEPLOY_MARKER ??
3212
+ null,
3177
3213
  });
3178
3214
  }
3179
3215
  if (url.pathname === '/staged-files/put') {
@@ -3683,6 +3719,10 @@ async function handleWorkflowRoute(input: {
3683
3719
  status: 'submitted',
3684
3720
  workflowInstanceId: instance.id,
3685
3721
  instanceState,
3722
+ runtimeDeployVersion:
3723
+ env.CF_VERSION_METADATA?.id ??
3724
+ env.DEEPLINE_COORDINATOR_DEPLOY_MARKER ??
3725
+ null,
3686
3726
  coordinatorTimings,
3687
3727
  });
3688
3728
  } finally {
@@ -1,6 +1,6 @@
1
1
  import { normalizePlayRunFailure } from '../../../shared_libs/play-runtime/run-failure';
2
2
 
3
- export const PLATFORM_DEPLOY_WORKFLOW_RETRY_LIMIT = 1;
3
+ export const PLATFORM_DEPLOY_WORKFLOW_RETRY_LIMIT = 5;
4
4
 
5
5
  export type WorkflowRetryDecision =
6
6
  | {
@@ -44,3 +44,17 @@ export function decideWorkflowPlatformRetry(input: {
44
44
  message: failure.message,
45
45
  };
46
46
  }
47
+
48
+ export function shouldPublishWorkflowRuntimeFailure(input: {
49
+ error: unknown;
50
+ retryAttempts: number;
51
+ }): boolean {
52
+ const message =
53
+ input.error instanceof Error ? input.error.message : String(input.error);
54
+ const decision = decideWorkflowPlatformRetry({
55
+ workflowStatus: 'errored',
56
+ error: message,
57
+ retryAttempts: input.retryAttempts,
58
+ });
59
+ return decision.action !== 'retry';
60
+ }
@@ -101,10 +101,10 @@ export const SDK_RELEASE = {
101
101
  // 0.1.108 ships explicit dataset column/tool recompute policy and removes
102
102
  // the SDK enrich generator's one-second stale policy.
103
103
  // 0.1.110 ships authored V2 prebuilts and required top-level play descriptions.
104
- version: '0.1.139',
104
+ version: '0.1.140',
105
105
  apiContract: '2026-06-dataset-column-cell-stale-hard-cutover',
106
106
  supportPolicy: {
107
- latest: '0.1.139',
107
+ latest: '0.1.140',
108
108
  minimumSupported: '0.1.53',
109
109
  deprecatedBelow: '0.1.53',
110
110
  commandMinimumSupported: [
@@ -13,6 +13,8 @@
13
13
  * The header is harmless when there is only one active version (the default).
14
14
  */
15
15
  export const COORDINATOR_VERSION_KEY_HEADER = 'Cloudflare-Workers-Version-Key';
16
+ export const COORDINATOR_VERSION_OVERRIDES_HEADER =
17
+ 'Cloudflare-Workers-Version-Overrides';
16
18
  /**
17
19
  * Shared secret the coordinator uses to authenticate dispatcher (Vercel app)
18
20
  * traffic. The coordinator also sanity-checks `x-deepline-run-scope` matches
@@ -65,6 +67,8 @@ export function coordinatorRequestHeaders(input: {
65
67
  runId: string;
66
68
  contentType?: string | null;
67
69
  internalToken?: string | null;
70
+ runtimeDeployVersion?: string | null;
71
+ coordinatorWorkerName?: string | null;
68
72
  /**
69
73
  * When set, the coordinator validates this matches the runId in the URL.
70
74
  * Pass the runId on `/cancel` / `/signal` calls so a leaked dispatcher
@@ -80,6 +84,19 @@ export function coordinatorRequestHeaders(input: {
80
84
  if (trimmed) {
81
85
  headers[COORDINATOR_VERSION_KEY_HEADER] = trimmed;
82
86
  }
87
+ const runtimeDeployVersion = input.runtimeDeployVersion?.trim();
88
+ const coordinatorWorkerName = input.coordinatorWorkerName?.trim();
89
+ if (
90
+ runtimeDeployVersion &&
91
+ coordinatorWorkerName &&
92
+ /^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i.test(
93
+ runtimeDeployVersion,
94
+ ) &&
95
+ /^[A-Za-z0-9_-]+$/.test(coordinatorWorkerName)
96
+ ) {
97
+ headers[COORDINATOR_VERSION_OVERRIDES_HEADER] =
98
+ `${coordinatorWorkerName}="${runtimeDeployVersion}"`;
99
+ }
83
100
  const internalToken =
84
101
  input.internalToken?.trim() || resolveInternalCoordinatorToken();
85
102
  if (internalToken) {
@@ -2,7 +2,7 @@ const CLOUDFLARE_DURABLE_OBJECT_RESET_RE =
2
2
  /Durable Object.*(?:code was updated|storage caused object)/;
3
3
 
4
4
  export const PLATFORM_DEPLOY_INTERRUPTED_MESSAGE =
5
- 'Run interrupted by a platform deploy and was not retried automatically. Re-run the same command; the input is unchanged.';
5
+ 'Run interrupted by a platform deploy. Deepline retries this automatically when possible; if this error is still visible, re-run the same command.';
6
6
 
7
7
  export const INTERNAL_RUNTIME_STORAGE_ERROR_MESSAGE =
8
8
  'Internal play runtime storage failed. Please retry the run; if this keeps happening, contact Deepline support with the run ID.';
@@ -1,3 +1,5 @@
1
+ import { normalizePlayRunFailure } from './run-failure';
2
+
1
3
  export type PlayRunLedgerStatus =
2
4
  | 'queued'
3
5
  | 'running'
@@ -560,6 +562,7 @@ function conflictingTerminalSnapshot(
560
562
  base: PlayRunLedgerSnapshot,
561
563
  eventType: keyof typeof TERMINAL_STATUS_BY_EVENT_TYPE,
562
564
  occurredAt: number,
565
+ eventError?: string | null,
563
566
  ): PlayRunLedgerSnapshot | null {
564
567
  if (!isTerminalPlayRunLedgerStatus(base.status)) {
565
568
  return null;
@@ -567,6 +570,18 @@ function conflictingTerminalSnapshot(
567
570
  if (TERMINAL_STATUS_BY_EVENT_TYPE[eventType] === base.status) {
568
571
  return null;
569
572
  }
573
+ if (
574
+ base.status === 'completed' &&
575
+ eventType === 'run.failed' &&
576
+ eventError &&
577
+ normalizePlayRunFailure(eventError).code === 'PLATFORM_DEPLOY_INTERRUPTED'
578
+ ) {
579
+ return withTiming(
580
+ appendLogLines(base, [
581
+ `[ledger] platform deploy terminal event ${eventType} ignored; status already ${base.status}`,
582
+ ]),
583
+ );
584
+ }
570
585
  const terminalAt = base.finishedAt ?? base.updatedAt ?? 0;
571
586
  if (occurredAt > terminalAt) {
572
587
  // Newer terminal evidence reconciles the run. This covers replay/receipt
@@ -683,7 +698,12 @@ export function reducePlayRunLedgerEvent(
683
698
  );
684
699
  case 'run.failed':
685
700
  return (
686
- conflictingTerminalSnapshot(base, event.type, occurredAt) ??
701
+ conflictingTerminalSnapshot(
702
+ base,
703
+ event.type,
704
+ occurredAt,
705
+ event.error,
706
+ ) ??
687
707
  withTiming({
688
708
  ...settleRunningStepsOnTerminal(base, 'failed', occurredAt),
689
709
  status: 'failed',
@@ -697,7 +717,12 @@ export function reducePlayRunLedgerEvent(
697
717
  );
698
718
  case 'run.cancelled':
699
719
  return (
700
- conflictingTerminalSnapshot(base, event.type, occurredAt) ??
720
+ conflictingTerminalSnapshot(
721
+ base,
722
+ event.type,
723
+ occurredAt,
724
+ event.error,
725
+ ) ??
701
726
  withTiming({
702
727
  ...settleRunningStepsOnTerminal(base, 'failed', occurredAt),
703
728
  status: 'cancelled',
@@ -141,6 +141,8 @@ export type PlaySchedulerSubmitInput = {
141
141
  coordinatorUrl?: string | null;
142
142
  /** Request-scoped coordinator auth token for non-production preview/dev runs. */
143
143
  coordinatorInternalToken?: string | null;
144
+ /** Runtime deploy generation/version that owns this run, when known. */
145
+ runtimeDeployVersion?: string | null;
144
146
  /** Request-scoped Vercel Deployment Protection bypass for preview runtime callbacks. */
145
147
  vercelProtectionBypassToken?: string | null;
146
148
  /** Millisecond epoch timestamp captured immediately before scheduler submit. */
@@ -213,6 +215,7 @@ export interface PlaySchedulerBackend {
213
215
  options?: {
214
216
  coordinatorUrl?: string | null;
215
217
  coordinatorInternalToken?: string | null;
218
+ runtimeDeployVersion?: string | null;
216
219
  initialState?: Record<string, unknown> | null;
217
220
  orgId?: string | null;
218
221
  },
package/dist/cli/index.js CHANGED
@@ -413,10 +413,10 @@ var SDK_RELEASE = {
413
413
  // 0.1.108 ships explicit dataset column/tool recompute policy and removes
414
414
  // the SDK enrich generator's one-second stale policy.
415
415
  // 0.1.110 ships authored V2 prebuilts and required top-level play descriptions.
416
- version: "0.1.139",
416
+ version: "0.1.140",
417
417
  apiContract: "2026-06-dataset-column-cell-stale-hard-cutover",
418
418
  supportPolicy: {
419
- latest: "0.1.139",
419
+ latest: "0.1.140",
420
420
  minimumSupported: "0.1.53",
421
421
  deprecatedBelow: "0.1.53",
422
422
  commandMinimumSupported: [
@@ -390,10 +390,10 @@ var SDK_RELEASE = {
390
390
  // 0.1.108 ships explicit dataset column/tool recompute policy and removes
391
391
  // the SDK enrich generator's one-second stale policy.
392
392
  // 0.1.110 ships authored V2 prebuilts and required top-level play descriptions.
393
- version: "0.1.139",
393
+ version: "0.1.140",
394
394
  apiContract: "2026-06-dataset-column-cell-stale-hard-cutover",
395
395
  supportPolicy: {
396
- latest: "0.1.139",
396
+ latest: "0.1.140",
397
397
  minimumSupported: "0.1.53",
398
398
  deprecatedBelow: "0.1.53",
399
399
  commandMinimumSupported: [
package/dist/index.js CHANGED
@@ -284,10 +284,10 @@ var SDK_RELEASE = {
284
284
  // 0.1.108 ships explicit dataset column/tool recompute policy and removes
285
285
  // the SDK enrich generator's one-second stale policy.
286
286
  // 0.1.110 ships authored V2 prebuilts and required top-level play descriptions.
287
- version: "0.1.139",
287
+ version: "0.1.140",
288
288
  apiContract: "2026-06-dataset-column-cell-stale-hard-cutover",
289
289
  supportPolicy: {
290
- latest: "0.1.139",
290
+ latest: "0.1.140",
291
291
  minimumSupported: "0.1.53",
292
292
  deprecatedBelow: "0.1.53",
293
293
  commandMinimumSupported: [
package/dist/index.mjs CHANGED
@@ -206,10 +206,10 @@ var SDK_RELEASE = {
206
206
  // 0.1.108 ships explicit dataset column/tool recompute policy and removes
207
207
  // the SDK enrich generator's one-second stale policy.
208
208
  // 0.1.110 ships authored V2 prebuilts and required top-level play descriptions.
209
- version: "0.1.139",
209
+ version: "0.1.140",
210
210
  apiContract: "2026-06-dataset-column-cell-stale-hard-cutover",
211
211
  supportPolicy: {
212
- latest: "0.1.139",
212
+ latest: "0.1.140",
213
213
  minimumSupported: "0.1.53",
214
214
  deprecatedBelow: "0.1.53",
215
215
  commandMinimumSupported: [
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "deepline",
3
- "version": "0.1.139",
3
+ "version": "0.1.140",
4
4
  "description": "Deepline SDK + CLI — B2B data enrichment powered by durable cloud execution",
5
5
  "license": "MIT",
6
6
  "repository": {