deepline 0.1.106 → 0.1.108

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/index.d.mts CHANGED
@@ -70,6 +70,8 @@ interface PlayStaticColumnProducer {
70
70
  toolId?: string;
71
71
  playId?: string;
72
72
  dependsOnFields?: string[];
73
+ recompute?: boolean;
74
+ recomputeOnError?: boolean;
73
75
  staleAfterSeconds?: number;
74
76
  conditional?: boolean;
75
77
  sourceRange?: PlayStaticSourceRange;
@@ -80,6 +82,8 @@ interface PlayStaticDatasetColumn {
80
82
  id: string;
81
83
  source: PlaySheetColumnSource;
82
84
  sqlName?: string;
85
+ recompute?: boolean;
86
+ recomputeOnError?: boolean;
83
87
  staleAfterSeconds?: number;
84
88
  producers: PlayStaticColumnProducer[];
85
89
  }
@@ -93,6 +97,8 @@ interface PlayStaticSourceRange {
93
97
  type PlayStaticSubstepMetadata = {
94
98
  conditional?: boolean;
95
99
  dependsOnFields?: string[];
100
+ recompute?: boolean;
101
+ recomputeOnError?: boolean;
96
102
  staleAfterSeconds?: number;
97
103
  };
98
104
  type PlayStaticSubstep = PlayStaticSubstepMetadata & ({
@@ -2979,6 +2985,8 @@ type ToolExecutionRequest = {
2979
2985
  input: Record<string, unknown>;
2980
2986
  /** Human-readable description for logs and run inspection. */
2981
2987
  description?: string;
2988
+ /** Recompute this tool call instead of reusing a durable receipt/checkpoint. */
2989
+ force?: boolean;
2982
2990
  /** Numeric TTL in seconds for this tool checkpoint. */
2983
2991
  staleAfterSeconds?: number;
2984
2992
  };
@@ -3031,6 +3039,10 @@ type DatasetColumnDefinition<Row, Value> = {
3031
3039
  run: (input: DatasetColumnRunInput<Row, Value>) => Value | Promise<Value>;
3032
3040
  /** Optional row-level gate. Skipped rows produce `null` for this column. */
3033
3041
  readonly runIf?: (row: Row, index: number) => boolean | Promise<boolean>;
3042
+ /** Recompute this cell on each run instead of reusing its durable value. */
3043
+ readonly recompute?: boolean;
3044
+ /** Recompute this cell when its durable value is an error-shaped object. */
3045
+ readonly recomputeOnError?: boolean;
3034
3046
  /** Fixed or value-dependent freshness policy for this cell. */
3035
3047
  readonly staleAfterSeconds?: StaleAfterSeconds<Value>;
3036
3048
  };
@@ -3049,6 +3061,10 @@ type ConditionalStepResolver<Row, Value, Else = null> = {
3049
3061
  type StepOptions<Row, Value = unknown> = {
3050
3062
  /** Optional row-level gate. Skipped rows produce `null` for this column. */
3051
3063
  readonly runIf?: (row: Row, index: number) => boolean | Promise<boolean>;
3064
+ /** Recompute this cell on each run instead of reusing its durable value. */
3065
+ readonly recompute?: boolean;
3066
+ /** Recompute this cell when its durable value is an error-shaped object. */
3067
+ readonly recomputeOnError?: boolean;
3052
3068
  /** Fixed or value-dependent freshness policy for this cell. */
3053
3069
  readonly staleAfterSeconds?: StaleAfterSeconds<Value>;
3054
3070
  };
@@ -3069,11 +3085,13 @@ type StepProgramResolver<Input, Return> = {
3069
3085
  };
3070
3086
  type PlayStepProgramStep = {
3071
3087
  readonly name: string;
3088
+ readonly recompute?: boolean;
3089
+ readonly recomputeOnError?: boolean;
3072
3090
  readonly staleAfterSeconds?: StaleAfterSeconds;
3073
3091
  readonly resolver: StepResolver<Record<string, unknown>, unknown> | ConditionalStepResolver<Record<string, unknown>, unknown> | StepProgramResolver<Record<string, unknown>, unknown>;
3074
3092
  };
3075
3093
  type ColumnResolver<Row, Value> = StepResolver<Row, Value> | ConditionalStepResolver<Row, Value> | StepProgramResolver<Row, Value>;
3076
- type StepProgramOutput<TProgram> = TProgram extends StepProgram<any, infer Output, any> ? Output : never;
3094
+ type StepProgramOutput<TProgram> = TProgram extends StepProgram<unknown, infer Output, unknown> ? Output : never;
3077
3095
  /**
3078
3096
  * Builder returned by `ctx.dataset(...)` for row-level durable columns.
3079
3097
  *
@@ -3315,9 +3333,7 @@ interface DeeplinePlayRuntimeContext {
3315
3333
  *
3316
3334
  * @sdkReference runtime 150 ctx.tools.execute(request)
3317
3335
  */
3318
- execute<TOutput = LoosePlayObject>(request: ToolExecutionRequest & {
3319
- staleAfterSeconds?: number;
3320
- }): Promise<ToolExecuteResult<TOutput>>;
3336
+ execute<TOutput = LoosePlayObject>(request: ToolExecutionRequest): Promise<ToolExecuteResult<TOutput>>;
3321
3337
  };
3322
3338
  /**
3323
3339
  * Execute a single tool by stable step key and tool ID.
@@ -3343,7 +3359,7 @@ interface DeeplinePlayRuntimeContext {
3343
3359
  *
3344
3360
  * @sdkReference runtime 180 ctx.runSteps(program, input, options)
3345
3361
  */
3346
- runSteps<TInput extends Record<string, unknown>, TOutput>(program: StepProgram<TInput, any, TOutput>, input: TInput, options?: {
3362
+ runSteps<TInput extends Record<string, unknown>, TOutput>(program: StepProgram<TInput, unknown, TOutput>, input: TInput, options?: {
3347
3363
  description?: string;
3348
3364
  }): Promise<TOutput>;
3349
3365
  /**
package/dist/index.d.ts CHANGED
@@ -70,6 +70,8 @@ interface PlayStaticColumnProducer {
70
70
  toolId?: string;
71
71
  playId?: string;
72
72
  dependsOnFields?: string[];
73
+ recompute?: boolean;
74
+ recomputeOnError?: boolean;
73
75
  staleAfterSeconds?: number;
74
76
  conditional?: boolean;
75
77
  sourceRange?: PlayStaticSourceRange;
@@ -80,6 +82,8 @@ interface PlayStaticDatasetColumn {
80
82
  id: string;
81
83
  source: PlaySheetColumnSource;
82
84
  sqlName?: string;
85
+ recompute?: boolean;
86
+ recomputeOnError?: boolean;
83
87
  staleAfterSeconds?: number;
84
88
  producers: PlayStaticColumnProducer[];
85
89
  }
@@ -93,6 +97,8 @@ interface PlayStaticSourceRange {
93
97
  type PlayStaticSubstepMetadata = {
94
98
  conditional?: boolean;
95
99
  dependsOnFields?: string[];
100
+ recompute?: boolean;
101
+ recomputeOnError?: boolean;
96
102
  staleAfterSeconds?: number;
97
103
  };
98
104
  type PlayStaticSubstep = PlayStaticSubstepMetadata & ({
@@ -2979,6 +2985,8 @@ type ToolExecutionRequest = {
2979
2985
  input: Record<string, unknown>;
2980
2986
  /** Human-readable description for logs and run inspection. */
2981
2987
  description?: string;
2988
+ /** Recompute this tool call instead of reusing a durable receipt/checkpoint. */
2989
+ force?: boolean;
2982
2990
  /** Numeric TTL in seconds for this tool checkpoint. */
2983
2991
  staleAfterSeconds?: number;
2984
2992
  };
@@ -3031,6 +3039,10 @@ type DatasetColumnDefinition<Row, Value> = {
3031
3039
  run: (input: DatasetColumnRunInput<Row, Value>) => Value | Promise<Value>;
3032
3040
  /** Optional row-level gate. Skipped rows produce `null` for this column. */
3033
3041
  readonly runIf?: (row: Row, index: number) => boolean | Promise<boolean>;
3042
+ /** Recompute this cell on each run instead of reusing its durable value. */
3043
+ readonly recompute?: boolean;
3044
+ /** Recompute this cell when its durable value is an error-shaped object. */
3045
+ readonly recomputeOnError?: boolean;
3034
3046
  /** Fixed or value-dependent freshness policy for this cell. */
3035
3047
  readonly staleAfterSeconds?: StaleAfterSeconds<Value>;
3036
3048
  };
@@ -3049,6 +3061,10 @@ type ConditionalStepResolver<Row, Value, Else = null> = {
3049
3061
  type StepOptions<Row, Value = unknown> = {
3050
3062
  /** Optional row-level gate. Skipped rows produce `null` for this column. */
3051
3063
  readonly runIf?: (row: Row, index: number) => boolean | Promise<boolean>;
3064
+ /** Recompute this cell on each run instead of reusing its durable value. */
3065
+ readonly recompute?: boolean;
3066
+ /** Recompute this cell when its durable value is an error-shaped object. */
3067
+ readonly recomputeOnError?: boolean;
3052
3068
  /** Fixed or value-dependent freshness policy for this cell. */
3053
3069
  readonly staleAfterSeconds?: StaleAfterSeconds<Value>;
3054
3070
  };
@@ -3069,11 +3085,13 @@ type StepProgramResolver<Input, Return> = {
3069
3085
  };
3070
3086
  type PlayStepProgramStep = {
3071
3087
  readonly name: string;
3088
+ readonly recompute?: boolean;
3089
+ readonly recomputeOnError?: boolean;
3072
3090
  readonly staleAfterSeconds?: StaleAfterSeconds;
3073
3091
  readonly resolver: StepResolver<Record<string, unknown>, unknown> | ConditionalStepResolver<Record<string, unknown>, unknown> | StepProgramResolver<Record<string, unknown>, unknown>;
3074
3092
  };
3075
3093
  type ColumnResolver<Row, Value> = StepResolver<Row, Value> | ConditionalStepResolver<Row, Value> | StepProgramResolver<Row, Value>;
3076
- type StepProgramOutput<TProgram> = TProgram extends StepProgram<any, infer Output, any> ? Output : never;
3094
+ type StepProgramOutput<TProgram> = TProgram extends StepProgram<unknown, infer Output, unknown> ? Output : never;
3077
3095
  /**
3078
3096
  * Builder returned by `ctx.dataset(...)` for row-level durable columns.
3079
3097
  *
@@ -3315,9 +3333,7 @@ interface DeeplinePlayRuntimeContext {
3315
3333
  *
3316
3334
  * @sdkReference runtime 150 ctx.tools.execute(request)
3317
3335
  */
3318
- execute<TOutput = LoosePlayObject>(request: ToolExecutionRequest & {
3319
- staleAfterSeconds?: number;
3320
- }): Promise<ToolExecuteResult<TOutput>>;
3336
+ execute<TOutput = LoosePlayObject>(request: ToolExecutionRequest): Promise<ToolExecuteResult<TOutput>>;
3321
3337
  };
3322
3338
  /**
3323
3339
  * Execute a single tool by stable step key and tool ID.
@@ -3343,7 +3359,7 @@ interface DeeplinePlayRuntimeContext {
3343
3359
  *
3344
3360
  * @sdkReference runtime 180 ctx.runSteps(program, input, options)
3345
3361
  */
3346
- runSteps<TInput extends Record<string, unknown>, TOutput>(program: StepProgram<TInput, any, TOutput>, input: TInput, options?: {
3362
+ runSteps<TInput extends Record<string, unknown>, TOutput>(program: StepProgram<TInput, unknown, TOutput>, input: TInput, options?: {
3347
3363
  description?: string;
3348
3364
  }): Promise<TOutput>;
3349
3365
  /**
package/dist/index.js CHANGED
@@ -270,12 +270,24 @@ var SDK_RELEASE = {
270
270
  // 0.1.105 ships the billing catalog surface: billing plans, subscribe,
271
271
  // subscription status/cancel, invoices, and the client.billing namespace.
272
272
  // 0.1.106 ships play cell provenance metadata and v2 preview retry hardening.
273
- version: "0.1.106",
273
+ // 0.1.107 ships the v2 quickstart command, the deepline-plays-quickstart
274
+ // skill on the sdk sync surface, and the people-search-to-email prebuilt.
275
+ // 0.1.108 ships explicit dataset column/tool recompute policy and removes
276
+ // the SDK enrich generator's one-second stale policy.
277
+ version: "0.1.108",
274
278
  apiContract: "2026-06-dataset-column-cell-stale-hard-cutover",
275
279
  supportPolicy: {
276
- latest: "0.1.106",
280
+ latest: "0.1.108",
277
281
  minimumSupported: "0.1.53",
278
- deprecatedBelow: "0.1.53"
282
+ deprecatedBelow: "0.1.53",
283
+ commandMinimumSupported: [
284
+ {
285
+ command: "enrich",
286
+ minimumSupported: "0.1.108",
287
+ reason: "Older SDK CLI enrich generated stale play source for the current dataset API."
288
+ }
289
+ ],
290
+ autoUpdatePatchLag: 2
279
291
  }
280
292
  };
281
293
 
@@ -875,6 +887,8 @@ function normalizeStepProgress(value) {
875
887
  value.artifactTableNamespace
876
888
  )
877
889
  } : {},
890
+ ...finiteNumber(value.startedAt) !== null ? { startedAt: finiteNumber(value.startedAt) } : {},
891
+ ...finiteNumber(value.completedAt) !== null ? { completedAt: finiteNumber(value.completedAt) } : {},
878
892
  ...finiteNumber(value.updatedAt) !== null ? { updatedAt: finiteNumber(value.updatedAt) } : {}
879
893
  };
880
894
  }
@@ -4065,7 +4079,9 @@ var DeeplineStepProgram = class _DeeplineStepProgram {
4065
4079
  resolver: stepResolver,
4066
4080
  ...options?.staleAfterSeconds !== void 0 ? {
4067
4081
  staleAfterSeconds: options.staleAfterSeconds
4068
- } : {}
4082
+ } : {},
4083
+ ...options?.recompute === true ? { recompute: true } : {},
4084
+ ...options?.recomputeOnError === true ? { recomputeOnError: true } : {}
4069
4085
  }
4070
4086
  ],
4071
4087
  this.returnResolver
package/dist/index.mjs CHANGED
@@ -192,12 +192,24 @@ var SDK_RELEASE = {
192
192
  // 0.1.105 ships the billing catalog surface: billing plans, subscribe,
193
193
  // subscription status/cancel, invoices, and the client.billing namespace.
194
194
  // 0.1.106 ships play cell provenance metadata and v2 preview retry hardening.
195
- version: "0.1.106",
195
+ // 0.1.107 ships the v2 quickstart command, the deepline-plays-quickstart
196
+ // skill on the sdk sync surface, and the people-search-to-email prebuilt.
197
+ // 0.1.108 ships explicit dataset column/tool recompute policy and removes
198
+ // the SDK enrich generator's one-second stale policy.
199
+ version: "0.1.108",
196
200
  apiContract: "2026-06-dataset-column-cell-stale-hard-cutover",
197
201
  supportPolicy: {
198
- latest: "0.1.106",
202
+ latest: "0.1.108",
199
203
  minimumSupported: "0.1.53",
200
- deprecatedBelow: "0.1.53"
204
+ deprecatedBelow: "0.1.53",
205
+ commandMinimumSupported: [
206
+ {
207
+ command: "enrich",
208
+ minimumSupported: "0.1.108",
209
+ reason: "Older SDK CLI enrich generated stale play source for the current dataset API."
210
+ }
211
+ ],
212
+ autoUpdatePatchLag: 2
201
213
  }
202
214
  };
203
215
 
@@ -797,6 +809,8 @@ function normalizeStepProgress(value) {
797
809
  value.artifactTableNamespace
798
810
  )
799
811
  } : {},
812
+ ...finiteNumber(value.startedAt) !== null ? { startedAt: finiteNumber(value.startedAt) } : {},
813
+ ...finiteNumber(value.completedAt) !== null ? { completedAt: finiteNumber(value.completedAt) } : {},
800
814
  ...finiteNumber(value.updatedAt) !== null ? { updatedAt: finiteNumber(value.updatedAt) } : {}
801
815
  };
802
816
  }
@@ -3987,7 +4001,9 @@ var DeeplineStepProgram = class _DeeplineStepProgram {
3987
4001
  resolver: stepResolver,
3988
4002
  ...options?.staleAfterSeconds !== void 0 ? {
3989
4003
  staleAfterSeconds: options.staleAfterSeconds
3990
- } : {}
4004
+ } : {},
4005
+ ...options?.recompute === true ? { recompute: true } : {},
4006
+ ...options?.recomputeOnError === true ? { recomputeOnError: true } : {}
3991
4007
  }
3992
4008
  ],
3993
4009
  this.returnResolver
@@ -1959,6 +1959,8 @@ type WorkerConditionalStepResolver = {
1959
1959
 
1960
1960
  type WorkerStepProgramStep = {
1961
1961
  name: string;
1962
+ recompute?: boolean;
1963
+ recomputeOnError?: boolean;
1962
1964
  staleAfterSeconds?: AuthoredStaleAfterSeconds;
1963
1965
  resolver:
1964
1966
  | WorkerStepResolver
@@ -1993,6 +1995,49 @@ type WorkerMapOptions = {
1993
1995
  onRowError?: 'isolate' | 'fail';
1994
1996
  };
1995
1997
 
1998
+ function authoredCellPolicyForWorkerStep(
1999
+ step: WorkerStepProgramStep,
2000
+ ): {
2001
+ recompute?: true;
2002
+ recomputeOnError?: true;
2003
+ staleAfterSeconds?: AuthoredStaleAfterSeconds;
2004
+ } | null {
2005
+ const policy = {
2006
+ ...(step.recompute === true ? { recompute: true as const } : {}),
2007
+ ...(step.recomputeOnError === true
2008
+ ? { recomputeOnError: true as const }
2009
+ : {}),
2010
+ ...(step.staleAfterSeconds !== undefined
2011
+ ? { staleAfterSeconds: step.staleAfterSeconds }
2012
+ : {}),
2013
+ };
2014
+ return Object.keys(policy).length > 0 ? policy : null;
2015
+ }
2016
+
2017
+ function workerCellPoliciesFromSteps(
2018
+ steps: readonly WorkerStepProgramStep[],
2019
+ ): CellStalenessPolicyByField {
2020
+ return Object.fromEntries(
2021
+ steps.flatMap((step) => {
2022
+ const policy = authoredCellPolicyForWorkerStep(step);
2023
+ return policy
2024
+ ? [[step.name, normalizeCellStalenessPolicy(policy)]]
2025
+ : [];
2026
+ }),
2027
+ ) as CellStalenessPolicyByField;
2028
+ }
2029
+
2030
+ function authoredWorkerCellPoliciesFromSteps(
2031
+ steps: readonly WorkerStepProgramStep[],
2032
+ ): AuthoredCellStalenessPolicyByField {
2033
+ return Object.fromEntries(
2034
+ steps.flatMap((step) => {
2035
+ const policy = authoredCellPolicyForWorkerStep(step);
2036
+ return policy ? [[step.name, policy]] : [];
2037
+ }),
2038
+ ) as AuthoredCellStalenessPolicyByField;
2039
+ }
2040
+
1996
2041
  /**
1997
2042
  * Per-cell terminal state recorded by map row execution and merged into the
1998
2043
  * Runtime Sheet row's `_cell_meta`. 'failed' carries the cell's error message;
@@ -2983,8 +3028,8 @@ function augmentSheetContractWithDatasetFields(input: {
2983
3028
  const field = typeof column.field === 'string' ? column.field : column.id;
2984
3029
  if (
2985
3030
  column.source === 'input' &&
2986
- field === input.contract.tableNamespace &&
2987
- !candidateFields.has(field)
3031
+ ((field === input.contract.tableNamespace && !candidateFields.has(field)) ||
3032
+ outputFields.has(field))
2988
3033
  ) {
2989
3034
  continue;
2990
3035
  }
@@ -4696,27 +4741,10 @@ function createMinimalWorkerCtx(
4696
4741
  const fields = Object.fromEntries(
4697
4742
  program.steps.map((step) => [step.name, step.resolver]),
4698
4743
  );
4699
- const cellPolicies = Object.fromEntries(
4700
- program.steps.flatMap((step) =>
4701
- step.staleAfterSeconds === undefined
4702
- ? []
4703
- : [
4704
- [
4705
- step.name,
4706
- normalizeCellStalenessPolicy({
4707
- staleAfterSeconds: step.staleAfterSeconds,
4708
- }),
4709
- ],
4710
- ],
4711
- ),
4712
- ) as CellStalenessPolicyByField;
4713
- const authoredCellPolicies = Object.fromEntries(
4714
- program.steps.flatMap((step) =>
4715
- step.staleAfterSeconds === undefined
4716
- ? []
4717
- : [[step.name, { staleAfterSeconds: step.staleAfterSeconds }]],
4718
- ),
4719
- ) as AuthoredCellStalenessPolicyByField;
4744
+ const cellPolicies = workerCellPoliciesFromSteps(program.steps);
4745
+ const authoredCellPolicies = authoredWorkerCellPoliciesFromSteps(
4746
+ program.steps,
4747
+ );
4720
4748
  return runMap(
4721
4749
  this.name,
4722
4750
  this.rows,
@@ -4944,27 +4972,10 @@ function createMinimalWorkerCtx(
4944
4972
  const fields = Object.fromEntries(
4945
4973
  fieldsDef.steps.map((step) => [step.name, step.resolver]),
4946
4974
  );
4947
- const cellPolicies = Object.fromEntries(
4948
- fieldsDef.steps.flatMap((step) =>
4949
- step.staleAfterSeconds === undefined
4950
- ? []
4951
- : [
4952
- [
4953
- step.name,
4954
- normalizeCellStalenessPolicy({
4955
- staleAfterSeconds: step.staleAfterSeconds,
4956
- }),
4957
- ],
4958
- ],
4959
- ),
4960
- ) as CellStalenessPolicyByField;
4961
- const authoredCellPolicies = Object.fromEntries(
4962
- fieldsDef.steps.flatMap((step) =>
4963
- step.staleAfterSeconds === undefined
4964
- ? []
4965
- : [[step.name, { staleAfterSeconds: step.staleAfterSeconds }]],
4966
- ),
4967
- ) as AuthoredCellStalenessPolicyByField;
4975
+ const cellPolicies = workerCellPoliciesFromSteps(fieldsDef.steps);
4976
+ const authoredCellPolicies = authoredWorkerCellPoliciesFromSteps(
4977
+ fieldsDef.steps,
4978
+ );
4968
4979
  return runMap(
4969
4980
  name,
4970
4981
  rows,
@@ -231,6 +231,8 @@ export type ToolExecutionRequest = {
231
231
  input: Record<string, unknown>;
232
232
  /** Human-readable description for logs and run inspection. */
233
233
  description?: string;
234
+ /** Recompute this tool call instead of reusing a durable receipt/checkpoint. */
235
+ force?: boolean;
234
236
  /** Numeric TTL in seconds for this tool checkpoint. */
235
237
  staleAfterSeconds?: number;
236
238
  };
@@ -294,6 +296,10 @@ export type DatasetColumnDefinition<Row, Value> = {
294
296
  run: (input: DatasetColumnRunInput<Row, Value>) => Value | Promise<Value>;
295
297
  /** Optional row-level gate. Skipped rows produce `null` for this column. */
296
298
  readonly runIf?: (row: Row, index: number) => boolean | Promise<boolean>;
299
+ /** Recompute this cell on each run instead of reusing its durable value. */
300
+ readonly recompute?: boolean;
301
+ /** Recompute this cell when its durable value is an error-shaped object. */
302
+ readonly recomputeOnError?: boolean;
297
303
  /** Fixed or value-dependent freshness policy for this cell. */
298
304
  readonly staleAfterSeconds?: StaleAfterSeconds<Value>;
299
305
  };
@@ -316,6 +322,10 @@ export type ConditionalStepResolver<Row, Value, Else = null> = {
316
322
  export type StepOptions<Row, Value = unknown> = {
317
323
  /** Optional row-level gate. Skipped rows produce `null` for this column. */
318
324
  readonly runIf?: (row: Row, index: number) => boolean | Promise<boolean>;
325
+ /** Recompute this cell on each run instead of reusing its durable value. */
326
+ readonly recompute?: boolean;
327
+ /** Recompute this cell when its durable value is an error-shaped object. */
328
+ readonly recomputeOnError?: boolean;
319
329
  /** Fixed or value-dependent freshness policy for this cell. */
320
330
  readonly staleAfterSeconds?: StaleAfterSeconds<Value>;
321
331
  };
@@ -351,6 +361,8 @@ export type StepProgramResolver<Input, Return> = {
351
361
 
352
362
  export type PlayStepProgramStep = {
353
363
  readonly name: string;
364
+ readonly recompute?: boolean;
365
+ readonly recomputeOnError?: boolean;
354
366
  readonly staleAfterSeconds?: StaleAfterSeconds;
355
367
  readonly resolver:
356
368
  | StepResolver<Record<string, unknown>, unknown>
@@ -364,7 +376,7 @@ export type ColumnResolver<Row, Value> =
364
376
  | StepProgramResolver<Row, Value>;
365
377
 
366
378
  export type StepProgramOutput<TProgram> =
367
- TProgram extends StepProgram<any, infer Output, any> ? Output : never;
379
+ TProgram extends StepProgram<unknown, infer Output, unknown> ? Output : never;
368
380
 
369
381
  /**
370
382
  * Builder returned by `ctx.dataset(...)` for row-level durable columns.
@@ -663,7 +675,7 @@ export interface DeeplinePlayRuntimeContext {
663
675
  * @sdkReference runtime 150 ctx.tools.execute(request)
664
676
  */
665
677
  execute<TOutput = LoosePlayObject>(
666
- request: ToolExecutionRequest & { staleAfterSeconds?: number },
678
+ request: ToolExecutionRequest,
667
679
  ): Promise<ToolExecuteResult<TOutput>>;
668
680
  };
669
681
  /**
@@ -694,7 +706,7 @@ export interface DeeplinePlayRuntimeContext {
694
706
  * @sdkReference runtime 180 ctx.runSteps(program, input, options)
695
707
  */
696
708
  runSteps<TInput extends Record<string, unknown>, TOutput>(
697
- program: StepProgram<TInput, any, TOutput>,
709
+ program: StepProgram<TInput, unknown, TOutput>,
698
710
  input: TInput,
699
711
  options?: { description?: string },
700
712
  ): Promise<TOutput>;
@@ -1128,6 +1140,10 @@ class DeeplineStepProgram<Input, Output, ReturnValue> implements StepProgram<
1128
1140
  options.staleAfterSeconds as PlayStepProgramStep['staleAfterSeconds'],
1129
1141
  }
1130
1142
  : {}),
1143
+ ...(options?.recompute === true ? { recompute: true } : {}),
1144
+ ...(options?.recomputeOnError === true
1145
+ ? { recomputeOnError: true }
1146
+ : {}),
1131
1147
  },
1132
1148
  ],
1133
1149
  this.returnResolver as StepResolver<
@@ -1598,7 +1614,8 @@ function emailStatusExtractorConfig(
1598
1614
  if (paths) config[key] = paths;
1599
1615
  }
1600
1616
  if (isRecord(value.statusMap)) {
1601
- config.statusMap = value.statusMap as EmailStatusExtractorConfig['statusMap'];
1617
+ config.statusMap =
1618
+ value.statusMap as EmailStatusExtractorConfig['statusMap'];
1602
1619
  }
1603
1620
  if (Array.isArray(value.rules)) {
1604
1621
  config.rules = value.rules as EmailStatusExtractorConfig['rules'];
@@ -1,8 +1,21 @@
1
1
  /**
2
2
  * Single source of truth for SDK release metadata.
3
3
  *
4
- * Edit THIS file to bump the SDK version, advance the support window, or rev
5
- * the SDK/API contract identifier. Everything else derives from these values:
4
+ * Ordinary SDK PRs do NOT bump `version` here. Patch version selection
5
+ * happens at publish time: on push to main, `.github/workflows/sdk-release.yml`
6
+ * (via `scripts/sdk-release-autobump.ts`) compares the built package against
7
+ * the published npm tarball and, when the content changed, stamps the next
8
+ * unpublished patch into `version` + `supportPolicy.latest` and publishes it
9
+ * in the same run.
10
+ *
11
+ * Edit THIS file by hand only for deliberate release decisions:
12
+ * - minor/major version bumps (set `version` and `supportPolicy.latest`),
13
+ * - `apiContract` cutovers (see `docs/sdk-runtime-compatibility.md`),
14
+ * - support-window moves (`minimumSupported` / `deprecatedBelow`).
15
+ * The automation never touches `apiContract`, `minimumSupported`, or
16
+ * `deprecatedBelow`.
17
+ *
18
+ * Everything else derives from these values:
6
19
  *
7
20
  * - `sdk/src/version.ts` re-exports `SDK_VERSION` and `SDK_API_CONTRACT`.
8
21
  * - `src/lib/sdk/release-policy.ts` re-exports `SDK_RELEASE_POLICY`.
@@ -13,8 +26,7 @@
13
26
  * `src/lib/sdk/api-routes.ts` and the apiContract here; the hash in
14
27
  * `contracts/sdk-api.manifest.hash` is the invariant that lands in git.
15
28
  *
16
- * Human editors should ONLY touch this file when releasing or changing
17
- * compatibility policy. Every other location is derived and any drift is a
29
+ * Any drift between this file and the derived locations is a
18
30
  * `check:sdk-release-readiness` failure with a one-shot fix command.
19
31
  */
20
32
 
@@ -34,10 +46,27 @@ export type SdkSupportPolicy = {
34
46
  * warns). Advance when a release becomes the new floor.
35
47
  */
36
48
  deprecatedBelow: string;
49
+ /**
50
+ * Command-scoped support floors for SDK CLI workflows whose local behavior
51
+ * can break while the network API contract remains compatible.
52
+ */
53
+ commandMinimumSupported?: ReadonlyArray<{
54
+ command: string;
55
+ minimumSupported: string;
56
+ reason: string;
57
+ }>;
58
+ /**
59
+ * Ask update-capable CLIs to self-update when they are this many patch
60
+ * releases behind latest, even if they are not blocked yet.
61
+ */
62
+ autoUpdatePatchLag?: number;
37
63
  };
38
64
 
39
65
  export type SdkRelease = {
40
- /** Version published to npm; the only place humans should bump it. */
66
+ /**
67
+ * Version published to npm. Usually stamped by the release workflow at
68
+ * publish time (auto-bump); edit by hand only for minor/major releases.
69
+ */
41
70
  version: string;
42
71
  /**
43
72
  * SDK/API contract identifier. Bump on incompatible protocol or schema
@@ -63,11 +92,24 @@ export const SDK_RELEASE = {
63
92
  // 0.1.105 ships the billing catalog surface: billing plans, subscribe,
64
93
  // subscription status/cancel, invoices, and the client.billing namespace.
65
94
  // 0.1.106 ships play cell provenance metadata and v2 preview retry hardening.
66
- version: '0.1.106',
95
+ // 0.1.107 ships the v2 quickstart command, the deepline-plays-quickstart
96
+ // skill on the sdk sync surface, and the people-search-to-email prebuilt.
97
+ // 0.1.108 ships explicit dataset column/tool recompute policy and removes
98
+ // the SDK enrich generator's one-second stale policy.
99
+ version: '0.1.108',
67
100
  apiContract: '2026-06-dataset-column-cell-stale-hard-cutover',
68
101
  supportPolicy: {
69
- latest: '0.1.106',
102
+ latest: '0.1.108',
70
103
  minimumSupported: '0.1.53',
71
104
  deprecatedBelow: '0.1.53',
105
+ commandMinimumSupported: [
106
+ {
107
+ command: 'enrich',
108
+ minimumSupported: '0.1.108',
109
+ reason:
110
+ 'Older SDK CLI enrich generated stale play source for the current dataset API.',
111
+ },
112
+ ],
113
+ autoUpdatePatchLag: 2,
72
114
  },
73
115
  } as const satisfies SdkRelease;
@@ -134,6 +134,10 @@ class WorkerStepProgram<Input, Output, ReturnValue> implements StepProgram<
134
134
  options.staleAfterSeconds as PlayStepProgramStep['staleAfterSeconds'],
135
135
  }
136
136
  : {}),
137
+ ...(options?.recompute === true ? { recompute: true } : {}),
138
+ ...(options?.recomputeOnError === true
139
+ ? { recomputeOnError: true }
140
+ : {}),
137
141
  },
138
142
  ],
139
143
  this.returnResolver as StepResolver<