deepline 0.1.153 → 0.1.154

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.
Files changed (48) hide show
  1. package/dist/bundling-sources/apps/play-runner-workers/src/coordinator-entry.ts +15 -0
  2. package/dist/bundling-sources/apps/play-runner-workers/src/entry.ts +1180 -825
  3. package/dist/bundling-sources/apps/play-runner-workers/src/runtime/batching.ts +34 -18
  4. package/dist/bundling-sources/apps/play-runner-workers/src/runtime/harness-receipt-store.ts +41 -0
  5. package/dist/bundling-sources/apps/play-runner-workers/src/runtime/receipts.ts +143 -8
  6. package/dist/bundling-sources/apps/play-runner-workers/src/runtime/tool-receipts.ts +104 -0
  7. package/dist/bundling-sources/sdk/src/index.ts +0 -1
  8. package/dist/bundling-sources/sdk/src/play.ts +3 -48
  9. package/dist/bundling-sources/sdk/src/plays/harness-stub.ts +27 -2
  10. package/dist/bundling-sources/sdk/src/release.ts +2 -2
  11. package/dist/bundling-sources/sdk/src/worker-play-entry.ts +0 -10
  12. package/dist/bundling-sources/shared_libs/play-data-plane/index.ts +0 -1
  13. package/dist/bundling-sources/shared_libs/play-runtime/app-runtime-api.ts +87 -0
  14. package/dist/bundling-sources/shared_libs/play-runtime/batch-runtime.ts +0 -59
  15. package/dist/bundling-sources/shared_libs/play-runtime/cell-staleness.ts +0 -253
  16. package/dist/bundling-sources/shared_libs/play-runtime/context.ts +805 -1570
  17. package/dist/bundling-sources/shared_libs/play-runtime/ctx-types.ts +47 -74
  18. package/dist/bundling-sources/shared_libs/play-runtime/default-batch-strategies.ts +36 -14
  19. package/dist/bundling-sources/shared_libs/play-runtime/durable-call-cache.ts +145 -0
  20. package/dist/bundling-sources/shared_libs/play-runtime/durable-receipt-execution.ts +284 -0
  21. package/dist/bundling-sources/shared_libs/play-runtime/postgres-json.ts +12 -5
  22. package/dist/bundling-sources/shared_libs/play-runtime/run-lifecycle-policy.ts +78 -0
  23. package/dist/bundling-sources/shared_libs/play-runtime/run-snapshot-stream.ts +10 -45
  24. package/dist/bundling-sources/shared_libs/play-runtime/runtime-actions.ts +1 -0
  25. package/dist/bundling-sources/shared_libs/play-runtime/runtime-api.ts +923 -535
  26. package/dist/bundling-sources/shared_libs/play-runtime/runtime-pg-driver-neon-serverless.ts +45 -76
  27. package/dist/bundling-sources/shared_libs/play-runtime/runtime-pg-driver.ts +12 -1
  28. package/dist/bundling-sources/shared_libs/play-runtime/step-program-dataset-builder.ts +1 -14
  29. package/dist/bundling-sources/shared_libs/play-runtime/tool-execution-outcome.ts +159 -0
  30. package/dist/bundling-sources/shared_libs/play-runtime/tool-result-types.ts +4 -1
  31. package/dist/bundling-sources/shared_libs/play-runtime/work-receipts.ts +32 -0
  32. package/dist/bundling-sources/shared_libs/plays/definition.ts +4 -2
  33. package/dist/bundling-sources/shared_libs/plays/runtime-validation.ts +3 -14
  34. package/dist/bundling-sources/shared_libs/plays/static-pipeline.ts +1 -43
  35. package/dist/cli/index.js +1301 -399
  36. package/dist/cli/index.mjs +1269 -361
  37. package/dist/{compiler-manifest-BjoRENv9.d.ts → compiler-manifest-DW1flrHk.d.mts} +0 -9
  38. package/dist/{compiler-manifest-BjoRENv9.d.mts → compiler-manifest-DW1flrHk.d.ts} +0 -9
  39. package/dist/index.d.mts +9 -38
  40. package/dist/index.d.ts +9 -38
  41. package/dist/index.js +22 -11
  42. package/dist/index.mjs +22 -11
  43. package/dist/plays/bundle-play-file.d.mts +2 -2
  44. package/dist/plays/bundle-play-file.d.ts +2 -2
  45. package/package.json +1 -1
  46. package/dist/bundling-sources/shared_libs/play-data-plane/cell-policy.ts +0 -76
  47. package/dist/bundling-sources/shared_libs/play-runtime/progress-emitter.ts +0 -197
  48. package/dist/bundling-sources/shared_libs/play-runtime/waterfall-replay.ts +0 -79
@@ -46,7 +46,6 @@
46
46
 
47
47
  import {
48
48
  registerRuntimePoolFactory,
49
- registerRuntimeOneShotQueryFactory,
50
49
  type RuntimePool,
51
50
  type RuntimePoolClient,
52
51
  } from './runtime-pg-driver';
@@ -91,15 +90,6 @@ interface NeonPoolConfig {
91
90
 
92
91
  interface NeonModule {
93
92
  Pool: new (config: NeonPoolConfig) => NeonPoolInstance;
94
- neon: (
95
- connectionString: string,
96
- options?: { fullResults?: boolean },
97
- ) => {
98
- query<R = Record<string, unknown>>(
99
- text: string,
100
- params?: unknown[],
101
- ): Promise<{ rows: R[] }>;
102
- };
103
93
  }
104
94
 
105
95
  function assertBindParams(params: unknown[] | undefined): void {
@@ -177,72 +167,51 @@ function wrapNeonPool(pool: NeonPoolInstance): RuntimePool {
177
167
  * until the import() resolves.
178
168
  */
179
169
  export function installNeonServerlessRuntimePoolDriver(): void {
180
- registerRuntimeOneShotQueryFactory((input) => {
181
- let sqlPromise: Promise<ReturnType<NeonModule['neon']>> | null = null;
182
- async function getSql(): Promise<ReturnType<NeonModule['neon']>> {
183
- if (!sqlPromise) {
184
- sqlPromise = loadNeonModule().then((neon) =>
185
- neon.neon(input.connectionString, { fullResults: true }),
186
- );
187
- }
188
- return sqlPromise;
189
- }
190
- return {
191
- query: async <
192
- R extends Record<string, unknown> = Record<string, unknown>,
193
- >(
194
- text: string,
195
- params?: unknown[],
196
- ) => {
197
- assertBindParams(params);
198
- const sql = await getSql();
199
- return await sql.query<R>(text, params);
200
- },
201
- };
202
- });
170
+ registerRuntimePoolFactory(
171
+ (input) => {
172
+ // Captured lazily so a Pool is only constructed if the play actually
173
+ // connects. Most plays that don't touch Postgres directly never even
174
+ // reach this branch — the factory is registered but never invoked.
175
+ let lazyPool: NeonPoolInstance | null = null;
203
176
 
204
- registerRuntimePoolFactory((input) => {
205
- // Captured lazily so a Pool is only constructed if the play actually
206
- // connects. Most plays that don't touch Postgres directly never even
207
- // reach this branch the factory is registered but never invoked.
208
- let lazyPool: NeonPoolInstance | null = null;
209
-
210
- /**
211
- * Resolve the lazy Pool, creating it on first call.
212
- *
213
- * Race safety: workerd executes within a single JS event loop, so
214
- * two concurrent `connect()` calls on the SAME wrapper run their
215
- * "lazyPool == null" checks in turn — the first creates the Pool,
216
- * the second sees it. No locking needed.
217
- *
218
- * If pool creation fails (e.g. DNS, bad connection string), the
219
- * error propagates out of connect() to the caller. We don't cache
220
- * a failed pool so retries can succeed on transient failures.
221
- */
222
- async function ensurePool(): Promise<NeonPoolInstance> {
223
- if (lazyPool) return lazyPool;
224
- const neon = await loadNeonModule();
225
- const pool = new neon.Pool({
226
- connectionString: input.connectionString,
227
- max: input.maxConnections ?? 4,
228
- idleTimeoutMillis: input.idleTimeoutMs ?? 15_000,
229
- connectionTimeoutMillis: input.connectTimeoutMs ?? 10_000,
230
- });
231
- lazyPool = pool;
232
- return pool;
233
- }
177
+ /**
178
+ * Resolve the lazy Pool, creating it on first call.
179
+ *
180
+ * Race safety: workerd executes within a single JS event loop, so
181
+ * two concurrent `connect()` calls on the SAME wrapper run their
182
+ * "lazyPool == null" checks in turn — the first creates the Pool,
183
+ * the second sees it. No locking needed.
184
+ *
185
+ * If pool creation fails (e.g. DNS, bad connection string), the
186
+ * error propagates out of connect() to the caller. We don't cache
187
+ * a failed pool so retries can succeed on transient failures.
188
+ */
189
+ async function ensurePool(): Promise<NeonPoolInstance> {
190
+ if (lazyPool) return lazyPool;
191
+ const neon = await loadNeonModule();
192
+ const pool = new neon.Pool({
193
+ connectionString: input.connectionString,
194
+ max: input.maxConnections ?? 4,
195
+ idleTimeoutMillis: input.idleTimeoutMs ?? 15_000,
196
+ connectionTimeoutMillis: input.connectTimeoutMs ?? 10_000,
197
+ });
198
+ lazyPool = pool;
199
+ return pool;
200
+ }
234
201
 
235
- return {
236
- connect: async () => {
237
- const pool = await ensurePool();
238
- return wrapNeonClient(await pool.connect());
239
- },
240
- end: async () => {
241
- if (lazyPool) {
242
- await lazyPool.end();
243
- lazyPool = null;
244
- }
245
- },
246
- };
247
- });
202
+ return {
203
+ connect: async () => {
204
+ const pool = await ensurePool();
205
+ return wrapNeonClient(await pool.connect());
206
+ },
207
+ end: async () => {
208
+ if (lazyPool) {
209
+ await lazyPool.end();
210
+ lazyPool = null;
211
+ }
212
+ },
213
+ };
214
+ },
215
+ { canReuseAcrossRequests: false },
216
+ );
248
217
  }
@@ -58,6 +58,7 @@ const runtimePgDriverRegistryKey = Symbol.for(
58
58
  type RuntimePgDriverRegistry = {
59
59
  poolFactory: RuntimePoolFactory | null;
60
60
  oneShotQueryFactory: RuntimeOneShotQueryFactory | null;
61
+ canReusePoolsAcrossRequests: boolean;
61
62
  };
62
63
 
63
64
  function getRuntimePgDriverRegistry(): RuntimePgDriverRegistry {
@@ -67,6 +68,7 @@ function getRuntimePgDriverRegistry(): RuntimePgDriverRegistry {
67
68
  globalWithRegistry[runtimePgDriverRegistryKey] ??= {
68
69
  poolFactory: null,
69
70
  oneShotQueryFactory: null,
71
+ canReusePoolsAcrossRequests: true,
70
72
  };
71
73
  return globalWithRegistry[runtimePgDriverRegistryKey];
72
74
  }
@@ -76,7 +78,10 @@ function getRuntimePgDriverRegistry(): RuntimePgDriverRegistry {
76
78
  * with different factories will throw to prevent silent driver swaps that
77
79
  * would otherwise drop in-flight pooled connections.
78
80
  */
79
- export function registerRuntimePoolFactory(factory: RuntimePoolFactory): void {
81
+ export function registerRuntimePoolFactory(
82
+ factory: RuntimePoolFactory,
83
+ options: { canReuseAcrossRequests?: boolean } = {},
84
+ ): void {
80
85
  const registry = getRuntimePgDriverRegistry();
81
86
  if (registry.poolFactory && registry.poolFactory !== factory) {
82
87
  throw new Error(
@@ -85,12 +90,17 @@ export function registerRuntimePoolFactory(factory: RuntimePoolFactory): void {
85
90
  );
86
91
  }
87
92
  registry.poolFactory = factory;
93
+ registry.canReusePoolsAcrossRequests = options.canReuseAcrossRequests ?? true;
88
94
  }
89
95
 
90
96
  export function isRuntimePoolFactoryRegistered(): boolean {
91
97
  return getRuntimePgDriverRegistry().poolFactory !== null;
92
98
  }
93
99
 
100
+ export function canReuseRuntimePostgresPoolsAcrossRequests(): boolean {
101
+ return getRuntimePgDriverRegistry().canReusePoolsAcrossRequests;
102
+ }
103
+
94
104
  export function registerRuntimeOneShotQueryFactory(
95
105
  factory: RuntimeOneShotQueryFactory,
96
106
  ): void {
@@ -146,4 +156,5 @@ export function __resetRuntimePoolFactoryForTests(): void {
146
156
  const registry = getRuntimePgDriverRegistry();
147
157
  registry.poolFactory = null;
148
158
  registry.oneShotQueryFactory = null;
159
+ registry.canReusePoolsAcrossRequests = true;
149
160
  }
@@ -1,13 +1,10 @@
1
- import type { AuthoredStaleAfterSeconds, PreviousCell } from './cell-staleness';
1
+ import type { PreviousCell } from './cell-staleness';
2
2
 
3
3
  export type StepProgramDatasetOptions = {
4
4
  runIf?: (
5
5
  row: Record<string, unknown>,
6
6
  index: number,
7
7
  ) => boolean | Promise<boolean>;
8
- recompute?: boolean;
9
- recomputeOnError?: boolean;
10
- staleAfterSeconds?: AuthoredStaleAfterSeconds;
11
8
  };
12
9
 
13
10
  export type StepProgramDatasetColumnRunInput<Value = unknown> = {
@@ -50,10 +47,7 @@ function isPreviousCell(value: unknown): value is PreviousCell {
50
47
 
51
48
  export type StepProgramDatasetStep<TResolver> = {
52
49
  name: string;
53
- recompute?: boolean;
54
- recomputeOnError?: boolean;
55
50
  resolver: TResolver;
56
- staleAfterSeconds?: AuthoredStaleAfterSeconds;
57
51
  };
58
52
 
59
53
  export type StepProgramDatasetProgram<TStep> = {
@@ -134,13 +128,6 @@ export class StepProgramDatasetBuilder<
134
128
  normalized.resolver,
135
129
  normalized.options,
136
130
  ),
137
- ...(normalized.options?.staleAfterSeconds !== undefined
138
- ? { staleAfterSeconds: normalized.options.staleAfterSeconds }
139
- : {}),
140
- ...(normalized.options?.recompute === true ? { recompute: true } : {}),
141
- ...(normalized.options?.recomputeOnError === true
142
- ? { recomputeOnError: true }
143
- : {}),
144
131
  } as TStep,
145
132
  ];
146
133
  return this;
@@ -0,0 +1,159 @@
1
+ import {
2
+ cloneToolExecuteResultWithExecution,
3
+ isToolExecuteResult,
4
+ type ToolExecuteResult,
5
+ type ToolResultExecutionMetadata,
6
+ } from './tool-result';
7
+
8
+ type OptionalKey = string | null | undefined;
9
+
10
+ type BaseToolExecutionOutcome = {
11
+ cacheKey?: OptionalKey;
12
+ };
13
+
14
+ export type ToolExecutionOutcome =
15
+ | (BaseToolExecutionOutcome & {
16
+ kind: 'live';
17
+ receiptKey?: OptionalKey;
18
+ })
19
+ | (BaseToolExecutionOutcome & {
20
+ kind: 'checkpoint';
21
+ })
22
+ | (BaseToolExecutionOutcome & {
23
+ kind: 'cache';
24
+ receiptKey: string;
25
+ attachedToReceiptKey?: OptionalKey;
26
+ })
27
+ | (BaseToolExecutionOutcome & {
28
+ kind: 'in_flight';
29
+ receiptKey: string;
30
+ attachedToReceiptKey?: OptionalKey;
31
+ });
32
+
33
+ export type DurableReceiptRecoverySource = 'cache' | 'in_flight' | 'owner';
34
+
35
+ function trimmed(value: OptionalKey): string | null {
36
+ const normalized = value?.trim();
37
+ return normalized ? normalized : null;
38
+ }
39
+
40
+ function optionalCacheKey(value: OptionalKey): Pick<
41
+ ToolResultExecutionMetadata,
42
+ 'cacheKey'
43
+ > {
44
+ const cacheKey = trimmed(value);
45
+ return cacheKey ? { cacheKey } : {};
46
+ }
47
+
48
+ function followerAttachment(input: {
49
+ receiptKey: string;
50
+ attachedToReceiptKey?: OptionalKey;
51
+ }): Pick<ToolResultExecutionMetadata, 'attachedToReceiptKey'> {
52
+ return {
53
+ attachedToReceiptKey:
54
+ trimmed(input.attachedToReceiptKey) ?? input.receiptKey,
55
+ };
56
+ }
57
+
58
+ export function toolExecutionMetadataForOutcome(
59
+ outcome: ToolExecutionOutcome,
60
+ ): ToolResultExecutionMetadata {
61
+ switch (outcome.kind) {
62
+ case 'live': {
63
+ const receiptKey = trimmed(outcome.receiptKey);
64
+ return {
65
+ idempotent: true,
66
+ cached: false,
67
+ source: 'live',
68
+ ...optionalCacheKey(outcome.cacheKey),
69
+ ...(receiptKey ? { receiptRole: 'owner' as const, receiptKey } : {}),
70
+ };
71
+ }
72
+ case 'checkpoint':
73
+ return {
74
+ idempotent: true,
75
+ cached: true,
76
+ source: 'checkpoint',
77
+ ...optionalCacheKey(outcome.cacheKey),
78
+ };
79
+ case 'cache': {
80
+ const receiptKey = trimmed(outcome.receiptKey);
81
+ if (!receiptKey) {
82
+ throw new Error('Cached durable tool results require a receipt key.');
83
+ }
84
+ return {
85
+ idempotent: true,
86
+ cached: true,
87
+ source: 'cache',
88
+ ...optionalCacheKey(outcome.cacheKey),
89
+ receiptRole: 'follower',
90
+ receiptKey,
91
+ ...followerAttachment({
92
+ receiptKey,
93
+ attachedToReceiptKey: outcome.attachedToReceiptKey,
94
+ }),
95
+ };
96
+ }
97
+ case 'in_flight': {
98
+ const receiptKey = trimmed(outcome.receiptKey);
99
+ if (!receiptKey) {
100
+ throw new Error('In-flight durable tool results require a receipt key.');
101
+ }
102
+ return {
103
+ idempotent: true,
104
+ cached: false,
105
+ source: 'in_flight',
106
+ ...optionalCacheKey(outcome.cacheKey),
107
+ receiptRole: 'follower',
108
+ receiptKey,
109
+ ...followerAttachment({
110
+ receiptKey,
111
+ attachedToReceiptKey: outcome.attachedToReceiptKey,
112
+ }),
113
+ };
114
+ }
115
+ default: {
116
+ const exhaustive: never = outcome;
117
+ return exhaustive;
118
+ }
119
+ }
120
+ }
121
+
122
+ export function toolExecutionOutcomeForDurableReceipt(input: {
123
+ source: DurableReceiptRecoverySource;
124
+ receiptKey: string;
125
+ cacheKey?: OptionalKey;
126
+ }): ToolExecutionOutcome {
127
+ return input.source === 'owner'
128
+ ? {
129
+ kind: 'live',
130
+ receiptKey: input.receiptKey,
131
+ cacheKey: input.cacheKey,
132
+ }
133
+ : {
134
+ kind: input.source,
135
+ receiptKey: input.receiptKey,
136
+ attachedToReceiptKey: input.receiptKey,
137
+ cacheKey: input.cacheKey,
138
+ };
139
+ }
140
+
141
+ export function cloneToolExecuteResultWithOutcome<TResult>(
142
+ value: ToolExecuteResult<TResult>,
143
+ outcome: ToolExecutionOutcome,
144
+ ): ToolExecuteResult<TResult> {
145
+ return cloneToolExecuteResultWithExecution(
146
+ value,
147
+ toolExecutionMetadataForOutcome(outcome),
148
+ );
149
+ }
150
+
151
+ export function markToolExecuteResultExecutionOutcome(
152
+ value: unknown,
153
+ outcome: ToolExecutionOutcome,
154
+ ): unknown {
155
+ if (!isToolExecuteResult(value)) {
156
+ return value;
157
+ }
158
+ return cloneToolExecuteResultWithOutcome(value, outcome);
159
+ }
@@ -5,8 +5,11 @@ import type { PlayDataset, SerializedPlayDataset } from '../plays/dataset';
5
5
  export type ToolResultExecutionMetadata = {
6
6
  idempotent: true;
7
7
  cached: boolean;
8
- source: 'live' | 'checkpoint' | 'cache';
8
+ source: 'live' | 'checkpoint' | 'cache' | 'in_flight';
9
9
  cacheKey?: string;
10
+ receiptRole?: 'owner' | 'follower';
11
+ receiptKey?: string;
12
+ attachedToReceiptKey?: string;
10
13
  };
11
14
 
12
15
  export type ToolResultTargetMetadata = {
@@ -18,6 +18,30 @@ export type WorkReceiptCommand = {
18
18
  runId: string;
19
19
  key: string;
20
20
  reclaimRunning?: boolean;
21
+ forceRefresh?: boolean;
22
+ };
23
+
24
+ export type WorkReceiptBatchClaimCommand = {
25
+ playName: string;
26
+ runId: string;
27
+ keys: string[];
28
+ reclaimRunning?: boolean;
29
+ forceRefresh?: boolean;
30
+ };
31
+
32
+ export type WorkReceiptBatchCompleteCommand = {
33
+ playName: string;
34
+ receipts: Array<{ runId: string; key: string; output: unknown }>;
35
+ };
36
+
37
+ export type WorkReceiptBatchFailCommand = {
38
+ playName: string;
39
+ receipts: Array<{ runId: string; key: string; error: string }>;
40
+ };
41
+
42
+ export type WorkReceiptGetCommand = {
43
+ playName: string;
44
+ key: string;
21
45
  };
22
46
 
23
47
  export type WorkReceiptClaim =
@@ -39,13 +63,21 @@ export type WorkReceiptClaim =
39
63
  };
40
64
 
41
65
  export type WorkReceiptStore = {
66
+ getReceipt?(input: WorkReceiptGetCommand): Promise<WorkReceipt | null>;
42
67
  claimReceipt(input: WorkReceiptCommand): Promise<WorkReceiptClaim>;
68
+ claimReceipts?(
69
+ input: WorkReceiptBatchClaimCommand,
70
+ ): Promise<WorkReceiptClaim[]>;
43
71
  completeReceipt(
44
72
  input: WorkReceiptCommand & { output: unknown },
45
73
  ): Promise<WorkReceipt | null>;
74
+ completeReceipts?(
75
+ input: WorkReceiptBatchCompleteCommand,
76
+ ): Promise<WorkReceipt[]>;
46
77
  failReceipt(
47
78
  input: WorkReceiptCommand & { error: string },
48
79
  ): Promise<WorkReceipt | null>;
80
+ failReceipts?(input: WorkReceiptBatchFailCommand): Promise<WorkReceipt[]>;
49
81
  };
50
82
 
51
83
  const SCOPED_WORK_RECEIPT_KEY_VERSION = 'ctxv2';
@@ -198,8 +198,10 @@ export function validatePlayStructuredDefinition(definition: unknown): {
198
198
  if (typedStep.type === 'tool' && !typedStep.toolId?.trim()) {
199
199
  errors.push(`Tool step ${typedStep.alias || index} requires toolId.`);
200
200
  }
201
- if (typedStep.type === 'waterfall' && !typedStep.tool?.trim()) {
202
- errors.push(`Waterfall step ${typedStep.alias || index} requires tool.`);
201
+ if (typedStep.type === 'waterfall') {
202
+ errors.push(
203
+ `Waterfall step ${typedStep.alias || index} is no longer supported. Use explicit tool steps or a steps(...) program.`,
204
+ );
203
205
  }
204
206
  if (typedStep.type === 'run_javascript') {
205
207
  if (!typedStep.execute?.source?.trim()) {
@@ -111,20 +111,9 @@ function validatePlayMapStructure(code: string): string[] {
111
111
  callExpression.callee.property.type === 'Identifier' &&
112
112
  callExpression.callee.property.name === 'waterfall'
113
113
  ) {
114
- const firstArgument = callExpression.arguments[0];
115
- if (firstArgument?.type === 'ObjectExpression') {
116
- const minResultsProperty = firstArgument.properties.find(
117
- (prop) =>
118
- prop.type === 'Property' &&
119
- prop.key.type === 'Identifier' &&
120
- prop.key.name === 'minResults',
121
- );
122
- if (!minResultsProperty) {
123
- errors.push(
124
- 'Inline ctx.waterfall({...}) calls must declare minResults.',
125
- );
126
- }
127
- }
114
+ errors.push(
115
+ 'ctx.waterfall(...) has been removed. Use explicit ctx.tools.execute(...) calls with steps(...) or ordinary TypeScript fallback logic.',
116
+ );
128
117
  }
129
118
  return;
130
119
  }
@@ -131,9 +131,6 @@ export interface PlayStaticColumnProducer {
131
131
  toolId?: string;
132
132
  playId?: string;
133
133
  dependsOnFields?: string[];
134
- recompute?: boolean;
135
- recomputeOnError?: boolean;
136
- staleAfterSeconds?: number;
137
134
  conditional?: boolean;
138
135
  sourceRange?: PlayStaticSourceRange;
139
136
  steps?: PlayStaticColumnProducer[];
@@ -144,9 +141,6 @@ export interface PlayStaticDatasetColumn {
144
141
  id: string;
145
142
  source: PlaySheetColumnSource;
146
143
  sqlName?: string;
147
- recompute?: boolean;
148
- recomputeOnError?: boolean;
149
- staleAfterSeconds?: number;
150
144
  producers: PlayStaticColumnProducer[];
151
145
  }
152
146
 
@@ -337,9 +331,6 @@ export interface PlayStaticSourceRange {
337
331
  type PlayStaticSubstepMetadata = {
338
332
  conditional?: boolean;
339
333
  dependsOnFields?: string[];
340
- recompute?: boolean;
341
- recomputeOnError?: boolean;
342
- staleAfterSeconds?: number;
343
334
  };
344
335
 
345
336
  export type PlayStaticSubstep = PlayStaticSubstepMetadata &
@@ -663,39 +654,11 @@ function compileDatasetColumns(
663
654
  sqlSafePlayColumnName(field),
664
655
  );
665
656
  if (!column) continue;
666
- const pipelineSubstep =
667
- substep.staleAfterSeconds === undefined &&
668
- substep.recompute !== true &&
669
- substep.recomputeOnError !== true
670
- ? pipelineSubsteps.find(
671
- (candidate) => fieldForColumnProducer(candidate) === field,
672
- )
673
- : undefined;
674
657
  const producer = columnProducerFromSubstep(
675
- pipelineSubstep &&
676
- (pipelineSubstep.staleAfterSeconds !== undefined ||
677
- pipelineSubstep.recompute === true ||
678
- pipelineSubstep.recomputeOnError === true)
679
- ? pipelineSubstep
680
- : substep,
658
+ substep,
681
659
  field,
682
660
  );
683
661
  column.producers.push(producer);
684
- if (
685
- column.staleAfterSeconds === undefined &&
686
- producer.staleAfterSeconds !== undefined
687
- ) {
688
- column.staleAfterSeconds = producer.staleAfterSeconds;
689
- }
690
- if (column.recompute !== true && producer.recompute === true) {
691
- column.recompute = true;
692
- }
693
- if (
694
- column.recomputeOnError !== true &&
695
- producer.recomputeOnError === true
696
- ) {
697
- column.recomputeOnError = true;
698
- }
699
662
  }
700
663
 
701
664
  return [...columnsById.values()];
@@ -745,11 +708,6 @@ function columnProducerFromSubstep(
745
708
  ...(substep.dependsOnFields?.length
746
709
  ? { dependsOnFields: [...substep.dependsOnFields] }
747
710
  : {}),
748
- ...(substep.recompute === true ? { recompute: true } : {}),
749
- ...(substep.recomputeOnError === true ? { recomputeOnError: true } : {}),
750
- ...(substep.staleAfterSeconds !== undefined
751
- ? { staleAfterSeconds: substep.staleAfterSeconds }
752
- : {}),
753
711
  ...(substep.conditional ? { conditional: true } : {}),
754
712
  ...(substep.sourceRange ? { sourceRange: substep.sourceRange } : {}),
755
713
  ...(steps && steps.length > 0 ? { steps } : {}),