deepline 0.1.243 → 0.1.245

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 (71) hide show
  1. package/README.md +1 -1
  2. package/dist/bundling-sources/sdk/src/plays/bundle-play-file.ts +5 -25
  3. package/dist/bundling-sources/sdk/src/release.ts +25 -26
  4. package/dist/bundling-sources/sdk/src/types.ts +1 -1
  5. package/dist/bundling-sources/shared_libs/play-runtime/backend.ts +2 -21
  6. package/dist/bundling-sources/shared_libs/play-runtime/governor/governor.ts +5 -6
  7. package/dist/bundling-sources/shared_libs/play-runtime/governor/policy.ts +6 -13
  8. package/dist/bundling-sources/shared_libs/play-runtime/governor/rate-state-backend.ts +9 -26
  9. package/dist/bundling-sources/shared_libs/play-runtime/internal-step-ids.ts +1 -2
  10. package/dist/bundling-sources/shared_libs/play-runtime/map-row-identity.ts +1 -1
  11. package/dist/bundling-sources/shared_libs/play-runtime/output-size-limits.ts +191 -29
  12. package/dist/bundling-sources/shared_libs/play-runtime/play-latency-trace.ts +1 -1
  13. package/dist/bundling-sources/shared_libs/play-runtime/providers.ts +1 -36
  14. package/dist/bundling-sources/shared_libs/play-runtime/run-ledger.ts +2 -3
  15. package/dist/bundling-sources/shared_libs/play-runtime/runner-backends/index.ts +0 -7
  16. package/dist/bundling-sources/shared_libs/play-runtime/runtime-api.ts +1 -12
  17. package/dist/bundling-sources/shared_libs/play-runtime/runtime-pg-driver-pg.ts +2 -3
  18. package/dist/bundling-sources/shared_libs/play-runtime/runtime-pg-driver.ts +5 -15
  19. package/dist/bundling-sources/shared_libs/play-runtime/scheduler-backend.ts +6 -21
  20. package/dist/bundling-sources/shared_libs/play-runtime/tool-result.ts +3 -4
  21. package/dist/bundling-sources/shared_libs/plays/artifact-kind-guard.ts +16 -29
  22. package/dist/bundling-sources/shared_libs/plays/artifact-types.ts +4 -8
  23. package/dist/bundling-sources/shared_libs/plays/bundling/index.ts +21 -712
  24. package/dist/bundling-sources/shared_libs/plays/bundling/limits.ts +1 -18
  25. package/dist/cli/index.js +28 -71
  26. package/dist/cli/index.mjs +28 -71
  27. package/dist/{compiler-manifest-CYcwzSOJ.d.ts → compiler-manifest-DlE7dnRm.d.mts} +2 -8
  28. package/dist/{compiler-manifest-CYcwzSOJ.d.mts → compiler-manifest-DlE7dnRm.d.ts} +2 -8
  29. package/dist/index.d.mts +2 -2
  30. package/dist/index.d.ts +2 -2
  31. package/dist/index.js +23 -22
  32. package/dist/index.mjs +23 -22
  33. package/dist/plays/bundle-play-file.d.mts +7 -22
  34. package/dist/plays/bundle-play-file.d.ts +7 -22
  35. package/dist/plays/bundle-play-file.mjs +26 -614
  36. package/package.json +2 -2
  37. package/dist/bundling-sources/apps/play-runner-workers/src/coordinator-entry.ts +0 -4504
  38. package/dist/bundling-sources/apps/play-runner-workers/src/dedup-do.ts +0 -1386
  39. package/dist/bundling-sources/apps/play-runner-workers/src/durable-object-deploy-handoff.ts +0 -30
  40. package/dist/bundling-sources/apps/play-runner-workers/src/entry.ts +0 -8385
  41. package/dist/bundling-sources/apps/play-runner-workers/src/runtime/README.md +0 -21
  42. package/dist/bundling-sources/apps/play-runner-workers/src/runtime/batching.ts +0 -251
  43. package/dist/bundling-sources/apps/play-runner-workers/src/runtime/coordinator-progress.ts +0 -289
  44. package/dist/bundling-sources/apps/play-runner-workers/src/runtime/csv-rows.ts +0 -85
  45. package/dist/bundling-sources/apps/play-runner-workers/src/runtime/customer-console.ts +0 -23
  46. package/dist/bundling-sources/apps/play-runner-workers/src/runtime/dataset-handles.ts +0 -528
  47. package/dist/bundling-sources/apps/play-runner-workers/src/runtime/harness-receipt-store.ts +0 -229
  48. package/dist/bundling-sources/apps/play-runner-workers/src/runtime/ledger-event-batches.ts +0 -81
  49. package/dist/bundling-sources/apps/play-runner-workers/src/runtime/live-progress.ts +0 -22
  50. package/dist/bundling-sources/apps/play-runner-workers/src/runtime/map-chunk-plan.ts +0 -920
  51. package/dist/bundling-sources/apps/play-runner-workers/src/runtime/map-latency-profile.ts +0 -90
  52. package/dist/bundling-sources/apps/play-runner-workers/src/runtime/output-datasets.ts +0 -475
  53. package/dist/bundling-sources/apps/play-runner-workers/src/runtime/receipts.ts +0 -570
  54. package/dist/bundling-sources/apps/play-runner-workers/src/runtime/result-dataset-persistence.ts +0 -50
  55. package/dist/bundling-sources/apps/play-runner-workers/src/runtime/row-isolation.ts +0 -5
  56. package/dist/bundling-sources/apps/play-runner-workers/src/runtime/run-work-dispatcher.ts +0 -519
  57. package/dist/bundling-sources/apps/play-runner-workers/src/runtime/tool-batch.ts +0 -107
  58. package/dist/bundling-sources/apps/play-runner-workers/src/runtime/tool-dispatch.ts +0 -2541
  59. package/dist/bundling-sources/apps/play-runner-workers/src/runtime/tool-http-errors.ts +0 -7
  60. package/dist/bundling-sources/apps/play-runner-workers/src/runtime/tool-receipts.ts +0 -227
  61. package/dist/bundling-sources/apps/play-runner-workers/src/runtime/work-budget.ts +0 -130
  62. package/dist/bundling-sources/apps/play-runner-workers/src/runtime/worker-platform-budget.ts +0 -39
  63. package/dist/bundling-sources/apps/play-runner-workers/src/runtime/workflow-preview.ts +0 -26
  64. package/dist/bundling-sources/apps/play-runner-workers/src/runtime-api-retry.ts +0 -23
  65. package/dist/bundling-sources/apps/play-runner-workers/src/workflow-instance-create.ts +0 -47
  66. package/dist/bundling-sources/apps/play-runner-workers/src/workflow-retry-state.ts +0 -167
  67. package/dist/bundling-sources/apps/play-runner-workers/src/workflow-retry.ts +0 -91
  68. package/dist/bundling-sources/sdk/src/plays/harness-stub.ts +0 -329
  69. package/dist/bundling-sources/sdk/src/worker-play-entry.ts +0 -240
  70. package/dist/bundling-sources/shared_libs/play-runtime/governor/coordinator-rate-state-backend.ts +0 -252
  71. package/dist/bundling-sources/shared_libs/play-runtime/runtime-pg-driver-neon-serverless.ts +0 -217
@@ -1,21 +0,0 @@
1
- # Per-play Worker Runtime
2
-
3
- These modules are bundled into every `esm_workers` play artifact. Keep them:
4
-
5
- - dependency-free, except for type-only imports
6
- - small enough to understand in one sitting
7
- - specific to the Cloudflare Worker execution path
8
-
9
- Do not import broad `shared_libs/play-runtime/*` modules here. Shared runtime
10
- modules are optimized for the Node runner and often bring along code
11
- that is correct but expensive in a per-graphHash Worker isolate.
12
-
13
- If a helper needs zod, Neon, runtime API transport, validation registries, or
14
- other heavy leaves, put it behind the `env.HARNESS` service binding in
15
- `apps/play-harness-worker` and call it through `sdk/src/plays/harness-stub.ts`.
16
-
17
- The intended split is:
18
-
19
- - `entry.ts`: request/workflow orchestration and ctx construction
20
- - `runtime/*`: tiny per-play primitives that must execute in the isolate
21
- - `apps/play-harness-worker`: heavy shared leaves kept warm behind RPC
@@ -1,251 +0,0 @@
1
- /**
2
- * Tiny batching helpers for the per-play Worker runtime.
3
- *
4
- * This mirrors the small subset of shared_libs/play-runtime batching that the
5
- * Workers harness needs without importing the broader shared runtime graph.
6
- */
7
-
8
- import type { AnyBatchOperationStrategy } from '../../../../shared_libs/play-runtime/batching-types';
9
-
10
- export type ChunkExecutionResult<TRequest, TResult> = {
11
- request: TRequest;
12
- result: TResult | null;
13
- /**
14
- * Present when this request's execution rejected. The request failed but
15
- * its siblings in the chunk kept their results — one provider hiccup must
16
- * stay a per-request failure, not a chunk-level abort that discards
17
- * completed sibling work.
18
- */
19
- error?: unknown;
20
- };
21
-
22
- function planExecutionChunks<TRequest>(
23
- requests: TRequest[],
24
- batchSize: number,
25
- maxChunkWeight: number | undefined,
26
- weightOf: ((request: TRequest) => number) | undefined,
27
- ): TRequest[][] {
28
- const maxUnits = Math.max(1, Math.floor(batchSize));
29
- const weightCap =
30
- maxChunkWeight != null && weightOf != null
31
- ? Math.max(1, Math.floor(maxChunkWeight))
32
- : null;
33
- const chunks: TRequest[][] = [];
34
- let current: TRequest[] = [];
35
- let weight = 0;
36
- for (const request of requests) {
37
- if (
38
- current.length > 0 &&
39
- (current.length >= maxUnits ||
40
- (weightCap != null && weight >= weightCap))
41
- ) {
42
- chunks.push(current);
43
- current = [];
44
- weight = 0;
45
- }
46
- current.push(request);
47
- if (weightCap != null && weightOf != null) {
48
- weight += Math.max(1, Math.floor(weightOf(request)));
49
- }
50
- }
51
- if (current.length > 0) chunks.push(current);
52
- return chunks;
53
- }
54
-
55
- export async function executeChunkedRequests<TRequest, TResult>(input: {
56
- requests: TRequest[];
57
- batchSize: number;
58
- maxChunkWeight?: number;
59
- weightOf?: (request: TRequest) => number;
60
- execute: (request: TRequest) => Promise<TResult>;
61
- onChunkComplete?: (
62
- results: Array<ChunkExecutionResult<TRequest, TResult>>,
63
- ) => void | Promise<void>;
64
- }): Promise<Array<ChunkExecutionResult<TRequest, TResult>>> {
65
- const results: Array<ChunkExecutionResult<TRequest, TResult>> = [];
66
- const chunks = planExecutionChunks(
67
- input.requests,
68
- input.batchSize,
69
- input.maxChunkWeight,
70
- input.weightOf,
71
- );
72
- for (const chunk of chunks) {
73
- let notifyChain: Promise<void> = Promise.resolve();
74
- const notify = async (
75
- entry: ChunkExecutionResult<TRequest, TResult>,
76
- ): Promise<void> => {
77
- results.push(entry);
78
- notifyChain = notifyChain.then(
79
- async () => await input.onChunkComplete?.([entry]),
80
- );
81
- await notifyChain;
82
- };
83
-
84
- await Promise.all(
85
- chunk.map(async (request) => {
86
- let entry: ChunkExecutionResult<TRequest, TResult>;
87
- try {
88
- entry = { request, result: await input.execute(request) };
89
- } catch (error) {
90
- entry = { request, result: null, error };
91
- }
92
- await notify(entry);
93
- }),
94
- );
95
- await notifyChain;
96
- }
97
- return results;
98
- }
99
-
100
- export function compileRequestsWithStrategy<TRequest>(input: {
101
- requests: TRequest[];
102
- strategy: AnyBatchOperationStrategy;
103
- getPayload: (request: TRequest) => Record<string, unknown>;
104
- }): Array<{
105
- batchOperation: string;
106
- memberRequests: TRequest[];
107
- batchPayload: Record<string, unknown>;
108
- splitResults: (value: unknown) => Array<unknown | null>;
109
- }> {
110
- const compiledBatches: Array<{
111
- batchOperation: string;
112
- memberRequests: TRequest[];
113
- batchPayload: Record<string, unknown>;
114
- splitResults: (value: unknown) => Array<unknown | null>;
115
- }> = [];
116
- const bucketedRequests = new Map<string, TRequest[]>();
117
- for (const request of input.requests) {
118
- const payload = input.getPayload(request);
119
- const bucketKey = String(input.strategy.toBucketKey(payload));
120
- const bucket = bucketedRequests.get(bucketKey);
121
- if (bucket) bucket.push(request);
122
- else bucketedRequests.set(bucketKey, [request]);
123
- }
124
- for (const bucketRequests of bucketedRequests.values()) {
125
- let currentBatch: TRequest[] = [];
126
- const flushBatch = () => {
127
- if (currentBatch.length === 0) return;
128
- const memberRequests = [...currentBatch];
129
- const compiled = input.strategy.compile(
130
- memberRequests.map((request) => input.getPayload(request)),
131
- );
132
- compiledBatches.push({
133
- batchOperation: compiled.batchOperation,
134
- memberRequests,
135
- batchPayload: compiled.batchPayload,
136
- splitResults: (value: unknown) => {
137
- const splitResults = input.strategy.splitResult(value, compiled);
138
- return memberRequests.map(
139
- (_, index) => splitResults[index]?.result ?? null,
140
- );
141
- },
142
- });
143
- currentBatch = [];
144
- };
145
- for (const request of bucketRequests) {
146
- const payload = input.getPayload(request);
147
- const canAppend =
148
- currentBatch.length > 0 &&
149
- currentBatch.length < input.strategy.maxBatchSize &&
150
- currentBatch.every((existing) =>
151
- input.strategy.canBatchWith(input.getPayload(existing), payload),
152
- );
153
- if (!canAppend && currentBatch.length > 0) flushBatch();
154
- currentBatch.push(request);
155
- }
156
- flushBatch();
157
- }
158
- return compiledBatches;
159
- }
160
-
161
- function testRateLimitBatchItems(
162
- value: unknown,
163
- ): Array<{ itemKey?: string; result?: unknown }> {
164
- if (!value || typeof value !== 'object' || Array.isArray(value)) {
165
- return [];
166
- }
167
- const record = value as Record<string, unknown>;
168
- if (Array.isArray(record.items)) {
169
- return record.items as Array<{ itemKey?: string; result?: unknown }>;
170
- }
171
- const candidates = [
172
- record.data,
173
- record.result,
174
- record.output,
175
- record.toolResponse &&
176
- typeof record.toolResponse === 'object' &&
177
- !Array.isArray(record.toolResponse)
178
- ? (record.toolResponse as Record<string, unknown>).raw
179
- : undefined,
180
- record.toolOutput &&
181
- typeof record.toolOutput === 'object' &&
182
- !Array.isArray(record.toolOutput)
183
- ? (record.toolOutput as Record<string, unknown>).raw
184
- : undefined,
185
- ];
186
- for (const candidate of candidates) {
187
- const items = testRateLimitBatchItems(candidate);
188
- if (items.length > 0) return items;
189
- }
190
- return [];
191
- }
192
-
193
- export function getDefaultPlayRuntimeBatchStrategy(
194
- operation: string | null | undefined,
195
- ): AnyBatchOperationStrategy | null {
196
- if (operation !== 'test_rate_limit') return null;
197
- return {
198
- sourceOperation: 'test_rate_limit',
199
- batchOperation: 'test_batch_rate_limit',
200
- kind: 'identifier_batch',
201
- maxBatchSize: 200,
202
- canBatchWith(left, right) {
203
- return String(left.stage || '') === String(right.stage || '');
204
- },
205
- toBucketKey(payload) {
206
- return `test_batch_rate_limit:${String(payload.stage || '')}`;
207
- },
208
- toItemKey(payload) {
209
- return String(payload.lead_id || payload.row_number || payload.key || '');
210
- },
211
- compile(payloads) {
212
- const stage = String(payloads[0]?.stage || '');
213
- const simulatedDelayMs =
214
- typeof payloads[0]?.simulated_delay_ms === 'number'
215
- ? payloads[0].simulated_delay_ms
216
- : undefined;
217
- const items = payloads.map((payload, index) => ({
218
- itemKey: String(
219
- payload.lead_id || payload.row_number || payload.key || `row_${index}`,
220
- ),
221
- payload,
222
- }));
223
- return {
224
- batchOperation: 'test_batch_rate_limit',
225
- batchPayload: {
226
- key: 'batch',
227
- ...(stage ? { stage } : {}),
228
- ...(simulatedDelayMs !== undefined
229
- ? { simulated_delay_ms: simulatedDelayMs }
230
- : {}),
231
- items,
232
- },
233
- items,
234
- };
235
- },
236
- splitResult(fullResult, compiled) {
237
- const resultItems = testRateLimitBatchItems(fullResult);
238
- return compiled.items.map((item, index) => ({
239
- itemKey: item.itemKey,
240
- result:
241
- index < resultItems.length
242
- ? (resultItems[index]?.result ?? null)
243
- : null,
244
- rawResult:
245
- index < resultItems.length
246
- ? (resultItems[index]?.result ?? null)
247
- : null,
248
- }));
249
- },
250
- };
251
- }
@@ -1,289 +0,0 @@
1
- import { coordinatorRequestHeaders } from '../../../../shared_libs/play-runtime/coordinator-headers';
2
- import type {
3
- LiveNodeProgressMap,
4
- LiveNodeProgressSnapshot,
5
- } from './live-progress';
6
-
7
- type CoordinatorProgressTraceExtra = {
8
- status: 'ok' | 'failed' | 'skipped_no_url';
9
- httpStatus?: number;
10
- activeNodeId?: string | null;
11
- activeArtifactTableNamespace?: string | null;
12
- activeCompleted?: number | null;
13
- activeTotal?: number | null;
14
- activeMessage?: string | null;
15
- };
16
-
17
- type CoordinatorProgressTrace = {
18
- phase: 'runner.coordinator_progress_publish';
19
- ms: number;
20
- extra: CoordinatorProgressTraceExtra;
21
- };
22
-
23
- export class CoordinatorProgressAuthorizationError extends Error {
24
- constructor(
25
- message: string,
26
- readonly status: number,
27
- ) {
28
- super(message);
29
- this.name = 'CoordinatorProgressAuthorizationError';
30
- }
31
- }
32
-
33
- export function isCoordinatorProgressAuthorizationError(
34
- error: unknown,
35
- ): error is CoordinatorProgressAuthorizationError {
36
- return (
37
- error instanceof CoordinatorProgressAuthorizationError ||
38
- (typeof error === 'object' &&
39
- error !== null &&
40
- 'name' in error &&
41
- 'status' in error &&
42
- (error as { name?: unknown }).name ===
43
- 'CoordinatorProgressAuthorizationError' &&
44
- typeof (error as { status?: unknown }).status === 'number')
45
- );
46
- }
47
-
48
- function activeProgressFields(liveNodeProgress: LiveNodeProgressMap): {
49
- activeNodeId: string | null;
50
- activeProgress: LiveNodeProgressSnapshot | null;
51
- activeArtifactTableNamespace: string | null;
52
- activeCompleted: number | null;
53
- activeTotal: number | null;
54
- activeMessage: string | null;
55
- } {
56
- const activeEntry =
57
- Object.entries(liveNodeProgress).find(
58
- ([, progress]) => typeof progress.completedAt !== 'number',
59
- ) ?? Object.entries(liveNodeProgress).at(-1);
60
- const activeNodeId = activeEntry?.[0] ?? null;
61
- const activeProgress = activeEntry?.[1] ?? null;
62
- const activeArtifactTableNamespace =
63
- typeof activeProgress?.artifactTableNamespace === 'string'
64
- ? activeProgress.artifactTableNamespace
65
- : null;
66
- const activeCompleted =
67
- typeof activeProgress?.completed === 'number'
68
- ? activeProgress.completed
69
- : null;
70
- const activeTotal =
71
- typeof activeProgress?.total === 'number' ? activeProgress.total : null;
72
- const activeMessage =
73
- typeof activeProgress?.message === 'string' ? activeProgress.message : null;
74
- return {
75
- activeNodeId,
76
- activeProgress,
77
- activeArtifactTableNamespace,
78
- activeCompleted,
79
- activeTotal,
80
- activeMessage,
81
- };
82
- }
83
-
84
- async function publishCoordinatorProgressEvent(input: {
85
- runId: string;
86
- coordinatorUrl?: string | null;
87
- coordinatorInternalToken?: string | null;
88
- occurredAt: number;
89
- runLogBuffer: string[];
90
- liveNodeProgress: LiveNodeProgressMap;
91
- fetchFn: typeof fetch;
92
- makeRequestId: () => string;
93
- nowMs: () => number;
94
- recordTrace: (trace: CoordinatorProgressTrace) => void;
95
- }): Promise<void> {
96
- const coordinatorUrl = input.coordinatorUrl?.trim();
97
- if (!coordinatorUrl) {
98
- input.recordTrace({
99
- phase: 'runner.coordinator_progress_publish',
100
- ms: 0,
101
- extra: { status: 'skipped_no_url' },
102
- });
103
- return;
104
- }
105
-
106
- const publishStartedAt = input.nowMs();
107
- const {
108
- activeNodeId,
109
- activeArtifactTableNamespace,
110
- activeCompleted,
111
- activeTotal,
112
- activeMessage,
113
- } = activeProgressFields(input.liveNodeProgress);
114
-
115
- const response = await input.fetchFn(
116
- `${coordinatorUrl.replace(/\/$/, '')}/dedup/${encodeURIComponent(
117
- input.runId,
118
- )}/event-add`,
119
- {
120
- method: 'POST',
121
- headers: {
122
- 'x-deepline-request-id': input.makeRequestId(),
123
- ...coordinatorRequestHeaders({
124
- runId: input.runId,
125
- contentType: 'application/json',
126
- internalToken: input.coordinatorInternalToken,
127
- }),
128
- },
129
- body: JSON.stringify({
130
- runId: input.runId,
131
- type: 'progress',
132
- status: 'running',
133
- ts: input.occurredAt,
134
- logs: input.runLogBuffer,
135
- activeNodeId,
136
- activeArtifactTableNamespace,
137
- updatedAt: input.occurredAt,
138
- liveNodeProgress: input.liveNodeProgress,
139
- }),
140
- },
141
- );
142
-
143
- if (response.status === 401 || response.status === 403) {
144
- input.recordTrace({
145
- phase: 'runner.coordinator_progress_publish',
146
- ms: input.nowMs() - publishStartedAt,
147
- extra: {
148
- status: 'failed',
149
- httpStatus: response.status,
150
- activeNodeId,
151
- activeArtifactTableNamespace,
152
- activeCompleted,
153
- activeTotal,
154
- activeMessage,
155
- },
156
- });
157
- throw new CoordinatorProgressAuthorizationError(
158
- `Coordinator progress publish was rejected with ${response.status}; ` +
159
- 'the play runner no longer has authority to update its coordinator state. ' +
160
- 'Stopping before more provider work can execute with stale coordinator authority.',
161
- response.status,
162
- );
163
- }
164
-
165
- if (!response.ok) {
166
- input.recordTrace({
167
- phase: 'runner.coordinator_progress_publish',
168
- ms: input.nowMs() - publishStartedAt,
169
- extra: {
170
- status: 'failed',
171
- httpStatus: response.status,
172
- activeNodeId,
173
- activeArtifactTableNamespace,
174
- activeCompleted,
175
- activeTotal,
176
- activeMessage,
177
- },
178
- });
179
- throw new Error(`coordinator progress event failed ${response.status}`);
180
- }
181
-
182
- input.recordTrace({
183
- phase: 'runner.coordinator_progress_publish',
184
- ms: input.nowMs() - publishStartedAt,
185
- extra: {
186
- status: 'ok',
187
- activeNodeId,
188
- activeArtifactTableNamespace,
189
- activeCompleted,
190
- activeTotal,
191
- activeMessage,
192
- },
193
- });
194
- }
195
-
196
- export function createCoordinatorProgressPublisher(input: {
197
- runId: string;
198
- coordinatorUrl?: string | null;
199
- coordinatorInternalToken?: string | null;
200
- abortController: AbortController;
201
- getRunLogBuffer: () => string[];
202
- getLiveNodeProgress: () => LiveNodeProgressMap;
203
- recordTrace: (trace: CoordinatorProgressTrace) => void;
204
- fetchFn?: typeof fetch;
205
- makeRequestId: () => string;
206
- nowMs: () => number;
207
- heartbeatIntervalMs: number;
208
- }): {
209
- assertHealthy: () => void;
210
- flush: (force: boolean) => Promise<void>;
211
- fatalError: () => Error | null;
212
- } {
213
- let lastPublishAt = 0;
214
- let publishInFlight: Promise<void> = Promise.resolve();
215
- let publishQueueDepth = 0;
216
- let fatalError: Error | null = null;
217
- const abortSignal = input.abortController.signal;
218
- const fetchFn = input.fetchFn ?? fetch;
219
-
220
- const markFatal = (error: Error): void => {
221
- fatalError ??= error;
222
- if (!abortSignal.aborted) {
223
- input.abortController.abort(error);
224
- }
225
- };
226
-
227
- const assertHealthy = (): void => {
228
- if (fatalError) {
229
- throw fatalError;
230
- }
231
- };
232
-
233
- const publish = async (occurredAt: number): Promise<void> => {
234
- assertHealthy();
235
- await publishCoordinatorProgressEvent({
236
- runId: input.runId,
237
- coordinatorUrl: input.coordinatorUrl,
238
- coordinatorInternalToken: input.coordinatorInternalToken,
239
- occurredAt,
240
- runLogBuffer: input.getRunLogBuffer(),
241
- liveNodeProgress: input.getLiveNodeProgress(),
242
- fetchFn,
243
- makeRequestId: input.makeRequestId,
244
- nowMs: input.nowMs,
245
- recordTrace: input.recordTrace,
246
- });
247
- };
248
-
249
- const flush = (force: boolean): Promise<void> => {
250
- if (fatalError) {
251
- return force ? Promise.reject(fatalError) : Promise.resolve();
252
- }
253
-
254
- const now = input.nowMs();
255
- if (!force && now - lastPublishAt < input.heartbeatIntervalMs) {
256
- return Promise.resolve();
257
- }
258
- if (!force && publishQueueDepth > 0) {
259
- return Promise.resolve();
260
- }
261
-
262
- lastPublishAt = now;
263
- publishQueueDepth += 1;
264
- const publishTask = publishInFlight
265
- .catch(() => undefined)
266
- .then(async () => {
267
- try {
268
- await publish(now);
269
- } finally {
270
- publishQueueDepth = Math.max(0, publishQueueDepth - 1);
271
- }
272
- });
273
-
274
- const handledPublishTask = publishTask.catch((error) => {
275
- if (isCoordinatorProgressAuthorizationError(error)) {
276
- markFatal(error);
277
- throw error;
278
- }
279
- });
280
- publishInFlight = handledPublishTask.catch(() => undefined);
281
- return force ? handledPublishTask : Promise.resolve();
282
- };
283
-
284
- return {
285
- assertHealthy,
286
- flush,
287
- fatalError: () => fatalError,
288
- };
289
- }
@@ -1,85 +0,0 @@
1
- import {
2
- cloneCsvAliasedRow,
3
- stripCsvProjectionMetadata,
4
- } from '../../../../shared_libs/play-runtime/csv-rename';
5
- import { copyMapRowOutcomeRuntimeFields } from '../../../../shared_libs/play-runtime/map-row-outcome';
6
-
7
- const CSV_TEMPLATE_CONTEXT = '__deeplineCsvProjectedValues';
8
-
9
- export type CsvRuntimeRow = Record<string, unknown>;
10
-
11
- function copyVisibleFields(
12
- row: CsvRuntimeRow,
13
- keepTemplateContext: boolean,
14
- ): CsvRuntimeRow {
15
- const publicRow: CsvRuntimeRow = {};
16
- for (const fieldName of Reflect.ownKeys(row)) {
17
- if (
18
- typeof fieldName === 'string' &&
19
- fieldName.startsWith('__deepline') &&
20
- (!keepTemplateContext || fieldName !== CSV_TEMPLATE_CONTEXT)
21
- ) {
22
- continue;
23
- }
24
- const descriptor = Object.getOwnPropertyDescriptor(row, fieldName);
25
- if (!descriptor) continue;
26
- Object.defineProperty(publicRow, fieldName, descriptor);
27
- }
28
- return publicRow;
29
- }
30
-
31
- function withCtx(
32
- row: CsvRuntimeRow,
33
- contextSource: CsvRuntimeRow = row,
34
- ): CsvRuntimeRow {
35
- const ctx = contextSource[CSV_TEMPLATE_CONTEXT];
36
- if (ctx) {
37
- const values = ctx as CsvRuntimeRow;
38
- for (const fieldName in values) {
39
- delete row[fieldName];
40
- row[fieldName] = values[fieldName];
41
- }
42
- }
43
- return row;
44
- }
45
-
46
- export function publicCsvInputRow<T extends CsvRuntimeRow>(row: T): T {
47
- return copyVisibleFields(stripCsvProjectionMetadata(row), false) as T;
48
- }
49
-
50
- export function runtimeCsvInputRow<T extends CsvRuntimeRow>(row: T): T {
51
- return withCtx(copyVisibleFields(cloneCsvAliasedRow(row), true)) as T;
52
- }
53
-
54
- export function runtimeCsvExecutionRow<T extends CsvRuntimeRow>(
55
- sourceRow: T,
56
- pendingRow?: CsvRuntimeRow | null,
57
- ): T {
58
- const source = runtimeCsvInputRow(sourceRow) as CsvRuntimeRow;
59
- if (!pendingRow) return source as T;
60
- const pending = runtimeCsvInputRow(pendingRow);
61
- const executionRow = { ...pending, ...source };
62
- if ('__deeplineCellMeta' in pendingRow) {
63
- executionRow.__deeplineCellMeta = pendingRow.__deeplineCellMeta;
64
- }
65
- return withCtx(executionRow) as T;
66
- }
67
-
68
- export function publicCsvOutputRow<T extends CsvRuntimeRow>(row: T): T {
69
- return publicCsvInputRow(row);
70
- }
71
-
72
- export function publicCsvStorageRow<T extends CsvRuntimeRow>(row: T): T {
73
- const publicRow = publicCsvInputRow(row) as CsvRuntimeRow;
74
- const storageRow: CsvRuntimeRow = {};
75
- for (const fieldName of Reflect.ownKeys(publicRow)) {
76
- if (typeof fieldName !== 'string') continue;
77
- storageRow[fieldName] = publicRow[fieldName];
78
- }
79
- return copyMapRowOutcomeRuntimeFields(storageRow, row) as T;
80
- }
81
-
82
- export function runtimeCsvStorageRow<T extends CsvRuntimeRow>(row: T): T {
83
- const storageRow = publicCsvStorageRow(row) as CsvRuntimeRow;
84
- return withCtx(storageRow, row) as T;
85
- }
@@ -1,23 +0,0 @@
1
- export function formatCustomerConsoleValue(value: unknown): string {
2
- if (typeof value === 'string') return value;
3
- try {
4
- if (value instanceof Error) return value.stack ?? value.message;
5
- if (value && typeof value === 'object') {
6
- const seen = new WeakSet<object>();
7
- const serialized = JSON.stringify(value, (_key, nested) => {
8
- if (typeof nested === 'symbol' || typeof nested === 'bigint') {
9
- return nested.toString();
10
- }
11
- if (nested && typeof nested === 'object') {
12
- if (seen.has(nested)) return '[Circular]';
13
- seen.add(nested);
14
- }
15
- return nested;
16
- });
17
- if (serialized !== undefined) return serialized;
18
- }
19
- return String(value);
20
- } catch {
21
- return '[Unprintable]';
22
- }
23
- }