deepline 0.1.153 → 0.1.155

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 +6 -4
  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 +1305 -401
  36. package/dist/cli/index.mjs +1273 -363
  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 +26 -13
  42. package/dist/index.mjs +26 -13
  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
@@ -169,6 +169,7 @@ type RuntimeApiRequest =
169
169
  runId: string;
170
170
  key: string;
171
171
  reclaimRunning?: boolean;
172
+ forceRefresh?: boolean;
172
173
  }
173
174
  | {
174
175
  action: 'complete_runtime_step_receipt';
@@ -190,6 +191,40 @@ type RuntimeApiRequest =
190
191
  runId: string;
191
192
  key: string;
192
193
  output?: unknown;
194
+ }
195
+ | {
196
+ action: 'get_runtime_step_receipts';
197
+ playName: string;
198
+ runId: string;
199
+ keys: string[];
200
+ }
201
+ | {
202
+ action: 'claim_runtime_step_receipts';
203
+ playName: string;
204
+ runId: string;
205
+ keys: string[];
206
+ reclaimRunning?: boolean;
207
+ forceRefresh?: boolean;
208
+ }
209
+ | {
210
+ action: 'complete_runtime_step_receipts';
211
+ playName: string;
212
+ runId: string;
213
+ receipts: Array<{
214
+ key: string;
215
+ runId: string;
216
+ output: unknown;
217
+ }>;
218
+ }
219
+ | {
220
+ action: 'fail_runtime_step_receipts';
221
+ playName: string;
222
+ runId: string;
223
+ receipts: Array<{
224
+ key: string;
225
+ runId: string;
226
+ error: string;
227
+ }>;
193
228
  };
194
229
 
195
230
  export type WorkerRuntimeApiContext = {
@@ -789,6 +824,19 @@ export async function getRuntimeStepReceiptViaAppRuntime(
789
824
  });
790
825
  }
791
826
 
827
+ export async function getRuntimeStepReceiptsViaAppRuntime(
828
+ context: WorkerRuntimeApiContext,
829
+ input: Omit<
830
+ Extract<RuntimeApiRequest, { action: 'get_runtime_step_receipts' }>,
831
+ 'action'
832
+ >,
833
+ ): Promise<RuntimeStepReceipt[]> {
834
+ return await postAppRuntimeApi<RuntimeStepReceipt[]>(context, {
835
+ action: 'get_runtime_step_receipts',
836
+ ...input,
837
+ });
838
+ }
839
+
792
840
  export async function claimRuntimeStepReceiptViaAppRuntime(
793
841
  context: WorkerRuntimeApiContext,
794
842
  input: Omit<
@@ -802,6 +850,19 @@ export async function claimRuntimeStepReceiptViaAppRuntime(
802
850
  });
803
851
  }
804
852
 
853
+ export async function claimRuntimeStepReceiptsViaAppRuntime(
854
+ context: WorkerRuntimeApiContext,
855
+ input: Omit<
856
+ Extract<RuntimeApiRequest, { action: 'claim_runtime_step_receipts' }>,
857
+ 'action'
858
+ >,
859
+ ): Promise<RuntimeStepReceipt[]> {
860
+ return await postAppRuntimeApi<RuntimeStepReceipt[]>(context, {
861
+ action: 'claim_runtime_step_receipts',
862
+ ...input,
863
+ });
864
+ }
865
+
805
866
  export async function completeRuntimeStepReceiptViaAppRuntime(
806
867
  context: WorkerRuntimeApiContext,
807
868
  input: Omit<
@@ -815,6 +876,19 @@ export async function completeRuntimeStepReceiptViaAppRuntime(
815
876
  });
816
877
  }
817
878
 
879
+ export async function completeRuntimeStepReceiptsViaAppRuntime(
880
+ context: WorkerRuntimeApiContext,
881
+ input: Omit<
882
+ Extract<RuntimeApiRequest, { action: 'complete_runtime_step_receipts' }>,
883
+ 'action'
884
+ >,
885
+ ): Promise<RuntimeStepReceipt[]> {
886
+ return await postAppRuntimeApi<RuntimeStepReceipt[]>(context, {
887
+ action: 'complete_runtime_step_receipts',
888
+ ...input,
889
+ });
890
+ }
891
+
818
892
  export async function failRuntimeStepReceiptViaAppRuntime(
819
893
  context: WorkerRuntimeApiContext,
820
894
  input: Omit<
@@ -828,6 +902,19 @@ export async function failRuntimeStepReceiptViaAppRuntime(
828
902
  });
829
903
  }
830
904
 
905
+ export async function failRuntimeStepReceiptsViaAppRuntime(
906
+ context: WorkerRuntimeApiContext,
907
+ input: Omit<
908
+ Extract<RuntimeApiRequest, { action: 'fail_runtime_step_receipts' }>,
909
+ 'action'
910
+ >,
911
+ ): Promise<RuntimeStepReceipt[]> {
912
+ return await postAppRuntimeApi<RuntimeStepReceipt[]>(context, {
913
+ action: 'fail_runtime_step_receipts',
914
+ ...input,
915
+ });
916
+ }
917
+
831
918
  export async function skipRuntimeStepReceiptViaAppRuntime(
832
919
  context: WorkerRuntimeApiContext,
833
920
  input: Omit<
@@ -148,62 +148,3 @@ export function compileRequestsWithStrategy<TRequest>(input: {
148
148
 
149
149
  return compiledBatches;
150
150
  }
151
-
152
- export async function executeWaterfallProviders<TRequest, TResult>(input: {
153
- providers: string[];
154
- getPendingRequests: () => TRequest[];
155
- getCachedResults: (
156
- provider: string,
157
- ) => Array<ChunkExecutionResult<TRequest, TResult>> | null;
158
- storeCachedResults: (
159
- provider: string,
160
- results: Array<ChunkExecutionResult<TRequest, TResult>>,
161
- ) => void;
162
- executeProviderRequests: (
163
- provider: string,
164
- requests: TRequest[],
165
- ) => Promise<Array<ChunkExecutionResult<TRequest, TResult>>>;
166
- onHit: (provider: string, request: TRequest, result: TResult) => void;
167
- onMiss: (provider: string, request: TRequest) => void;
168
- onProviderComplete?: (provider: string) => void;
169
- }): Promise<void> {
170
- for (const provider of input.providers) {
171
- const cached = input.getCachedResults(provider);
172
- if (cached) {
173
- for (const entry of cached) {
174
- if (entry.result != null) {
175
- input.onHit(provider, entry.request, entry.result);
176
- }
177
- }
178
- input.onProviderComplete?.(provider);
179
- continue;
180
- }
181
-
182
- const pending = input.getPendingRequests();
183
- if (pending.length === 0) {
184
- return;
185
- }
186
-
187
- const results = await input.executeProviderRequests(provider, pending);
188
- input.storeCachedResults(provider, results);
189
-
190
- for (const entry of results) {
191
- if (entry.result != null) {
192
- input.onHit(provider, entry.request, entry.result);
193
- } else {
194
- input.onMiss(provider, entry.request);
195
- }
196
- }
197
-
198
- input.onProviderComplete?.(provider);
199
- }
200
- }
201
-
202
- export function resolveWaterfallToolId(
203
- provider: string,
204
- toolName: string,
205
- ): string {
206
- return toolName.startsWith(`${provider}_`)
207
- ? toolName
208
- : `${provider}_${toolName}`;
209
- }
@@ -1,33 +1,3 @@
1
- /**
2
- * Resolve the next expiry window from a completed cell value.
3
- *
4
- * Return a positive whole number of seconds to set the next `staleAt`, or
5
- * `null` when this particular value should not expire.
6
- */
7
- export type StaleAfterSecondsResolver<Value = unknown> = (
8
- value: Value,
9
- ) => number | null;
10
-
11
- /** Authored freshness policy: fixed TTL seconds or a value-based resolver. */
12
- export type AuthoredStaleAfterSeconds<Value = unknown> =
13
- | number
14
- | StaleAfterSecondsResolver<Value>;
15
-
16
- /** Freshness policy as written by play authors before runtime normalization. */
17
- export type AuthoredCellStalenessPolicy<Value = unknown> = {
18
- recompute?: boolean;
19
- recomputeOnError?: boolean;
20
- staleAfterSeconds?: AuthoredStaleAfterSeconds<Value>;
21
- };
22
-
23
- /** Runtime-normalized freshness policy stored in execution plans. */
24
- export type CellStalenessPolicy = {
25
- recompute?: boolean;
26
- recomputeOnError?: boolean;
27
- staleAfterSeconds?: number;
28
- dynamicStaleAfterSeconds?: boolean;
29
- };
30
-
31
1
  /** Stored per-cell freshness and completion metadata. */
32
2
  export type CellStalenessMeta = {
33
3
  status?: string | null;
@@ -56,101 +26,8 @@ export type PreviousCell<Value = unknown> = {
56
26
  staleAfterSeconds?: number;
57
27
  };
58
28
 
59
- export type CellStalenessDecision =
60
- | {
61
- action: 'recompute';
62
- reason: 'missing' | 'failed' | 'forced' | 'stale';
63
- }
64
- | { action: 'reuse'; reason: 'fresh' | 'no_policy' | 'no_expiry' };
65
-
66
- export type CellStalenessPolicyByField = Record<string, CellStalenessPolicy>;
67
- export type AuthoredCellStalenessPolicyByField = Record<
68
- string,
69
- AuthoredCellStalenessPolicy
70
- >;
71
-
72
29
  export const DEEPLINE_CELL_META_FIELD = '__deeplineCellMeta';
73
30
 
74
- export function validateStaleAfterSeconds(
75
- staleAfterSeconds: number | undefined,
76
- label = 'staleAfterSeconds',
77
- ): void {
78
- if (staleAfterSeconds === undefined) {
79
- return;
80
- }
81
- if (
82
- !Number.isFinite(staleAfterSeconds) ||
83
- !Number.isInteger(staleAfterSeconds) ||
84
- staleAfterSeconds <= 0
85
- ) {
86
- throw new Error(`${label} must be a positive whole number of seconds.`);
87
- }
88
- }
89
-
90
- export function normalizeCellStalenessPolicy(
91
- policy: AuthoredCellStalenessPolicy | undefined,
92
- ): CellStalenessPolicy {
93
- if (
94
- policy?.recompute !== undefined &&
95
- typeof policy.recompute !== 'boolean'
96
- ) {
97
- throw new Error('recompute must be a boolean.');
98
- }
99
- if (
100
- policy?.recomputeOnError !== undefined &&
101
- typeof policy.recomputeOnError !== 'boolean'
102
- ) {
103
- throw new Error('recomputeOnError must be a boolean.');
104
- }
105
- const recompute = policy?.recompute === true;
106
- const recomputeOnError = policy?.recomputeOnError === true;
107
- const flags = {
108
- ...(recompute ? { recompute: true } : {}),
109
- ...(recomputeOnError ? { recomputeOnError: true } : {}),
110
- };
111
- const staleAfterSeconds = policy?.staleAfterSeconds;
112
- if (staleAfterSeconds === undefined) {
113
- return flags;
114
- }
115
- if (typeof staleAfterSeconds === 'function') {
116
- return {
117
- ...flags,
118
- dynamicStaleAfterSeconds: true,
119
- };
120
- }
121
- validateStaleAfterSeconds(staleAfterSeconds);
122
- return { ...flags, staleAfterSeconds };
123
- }
124
-
125
- export function resolveCompletedCellStalenessMeta<Value>(input: {
126
- policy?: AuthoredCellStalenessPolicy<Value>;
127
- value: Value;
128
- completedAt: number;
129
- }): Pick<CellStalenessMeta, 'staleAfterSeconds' | 'staleAt'> {
130
- const staleAfterSeconds = input.policy?.staleAfterSeconds;
131
- if (staleAfterSeconds === undefined) {
132
- return {};
133
- }
134
-
135
- const resolved =
136
- typeof staleAfterSeconds === 'function'
137
- ? staleAfterSeconds(input.value)
138
- : staleAfterSeconds;
139
- if (resolved === null) {
140
- return { staleAt: null };
141
- }
142
- if (typeof resolved !== 'number') {
143
- throw new Error(
144
- 'staleAfterSeconds(value) must return a positive whole number of seconds or null.',
145
- );
146
- }
147
- validateStaleAfterSeconds(resolved, 'staleAfterSeconds(value)');
148
- return {
149
- staleAfterSeconds: resolved,
150
- staleAt: input.completedAt + resolved * 1000,
151
- };
152
- }
153
-
154
31
  export function previousCellFromValue<Value>(input: {
155
32
  hasValue: boolean;
156
33
  value: Value;
@@ -187,133 +64,3 @@ export function previousCellFromValue<Value>(input: {
187
64
  }
188
65
  return previous;
189
66
  }
190
-
191
- export function shouldRecomputeCell(input: {
192
- hasValue: boolean;
193
- value?: unknown;
194
- meta?: CellStalenessMeta | null;
195
- policy?: CellStalenessPolicy;
196
- nowMs?: number;
197
- }): CellStalenessDecision {
198
- if (!input.hasValue) {
199
- return { action: 'recompute', reason: 'missing' };
200
- }
201
-
202
- const status = String(input.meta?.status ?? '').trim();
203
- if (status === 'failed') {
204
- return { action: 'recompute', reason: 'failed' };
205
- }
206
-
207
- if (input.policy?.recompute === true) {
208
- return { action: 'recompute', reason: 'forced' };
209
- }
210
-
211
- if (
212
- input.policy?.recomputeOnError === true &&
213
- isErrorLikeCellValue(input.value)
214
- ) {
215
- return { action: 'recompute', reason: 'failed' };
216
- }
217
-
218
- const staleAt =
219
- input.meta && Object.prototype.hasOwnProperty.call(input.meta, 'staleAt')
220
- ? input.meta.staleAt
221
- : undefined;
222
- if (staleAt === null) {
223
- return { action: 'reuse', reason: 'no_expiry' };
224
- }
225
- if (typeof staleAt === 'number' && Number.isFinite(staleAt)) {
226
- return (input.nowMs ?? Date.now()) > staleAt
227
- ? { action: 'recompute', reason: 'stale' }
228
- : { action: 'reuse', reason: 'fresh' };
229
- }
230
-
231
- if (input.policy?.dynamicStaleAfterSeconds) {
232
- return { action: 'recompute', reason: 'stale' };
233
- }
234
-
235
- const staleAfterSeconds = input.policy?.staleAfterSeconds;
236
- validateStaleAfterSeconds(staleAfterSeconds);
237
- if (staleAfterSeconds === undefined) {
238
- return { action: 'reuse', reason: 'no_policy' };
239
- }
240
-
241
- const completedAt =
242
- typeof input.meta?.completedAt === 'number' &&
243
- Number.isFinite(input.meta.completedAt)
244
- ? input.meta.completedAt
245
- : null;
246
- if (completedAt === null) {
247
- return { action: 'recompute', reason: 'missing' };
248
- }
249
-
250
- const ageMs = Math.max(0, (input.nowMs ?? Date.now()) - completedAt);
251
- return ageMs > staleAfterSeconds * 1000
252
- ? { action: 'recompute', reason: 'stale' }
253
- : { action: 'reuse', reason: 'fresh' };
254
- }
255
-
256
- export function resolveReusableCellMetaForCurrentPolicy<Value>(input: {
257
- hasValue: boolean;
258
- value: Value;
259
- meta?: CellStalenessMeta | null;
260
- policy?: AuthoredCellStalenessPolicy<Value>;
261
- }): Pick<CellStalenessMeta, 'staleAfterSeconds' | 'staleAt'> {
262
- if (
263
- !input.hasValue ||
264
- typeof input.policy?.staleAfterSeconds !== 'function'
265
- ) {
266
- return {};
267
- }
268
- const status = String(input.meta?.status ?? '').trim();
269
- if (status === 'failed') {
270
- return {};
271
- }
272
- const completedAt =
273
- typeof input.meta?.completedAt === 'number' &&
274
- Number.isFinite(input.meta.completedAt)
275
- ? input.meta.completedAt
276
- : null;
277
- if (completedAt === null) {
278
- return {};
279
- }
280
- return resolveCompletedCellStalenessMeta({
281
- policy: input.policy,
282
- value: input.value,
283
- completedAt,
284
- });
285
- }
286
-
287
- export function cellPolicyFields(
288
- policies: CellStalenessPolicyByField | undefined,
289
- ): string[] {
290
- if (!policies) {
291
- return [];
292
- }
293
- return Object.entries(policies)
294
- .filter(
295
- ([, policy]) =>
296
- policy.staleAfterSeconds !== undefined ||
297
- policy.dynamicStaleAfterSeconds === true ||
298
- policy.recompute === true ||
299
- policy.recomputeOnError === true,
300
- )
301
- .map(([field]) => field);
302
- }
303
-
304
- function isErrorLikeCellValue(value: unknown): boolean {
305
- if (typeof value === 'string') {
306
- return /(^|: )error(:|$)/i.test(value.trim());
307
- }
308
- if (!value || typeof value !== 'object' || Array.isArray(value)) {
309
- return false;
310
- }
311
- const record = value as Record<string, unknown>;
312
- const raw = (record.toolResponse as { raw?: unknown } | undefined)?.raw;
313
- return (
314
- (raw !== undefined && isErrorLikeCellValue(raw)) ||
315
- (typeof record.error === 'string' && record.error.trim().length > 0) ||
316
- record.status === 'failed' ||
317
- record.status === 'error'
318
- );
319
- }