deepline 0.1.151 → 0.1.153

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.
@@ -1101,12 +1101,11 @@ async function markWorkflowRuntimeFailure(input: {
1101
1101
  const shouldPreserveRawError =
1102
1102
  failure.code === 'RUN_FAILED' ||
1103
1103
  (failure.cause !== undefined && failure.message === failure.cause);
1104
- const normalizedError =
1105
- shouldPreserveRawError
1106
- ? `DynamicWorkflow runner failed: ${errorName}: ${errorMessage}${
1107
- errorStack ? `\n${errorStack}` : ''
1108
- }`
1109
- : `DynamicWorkflow runner failed: ${failure.message}`;
1104
+ const normalizedError = shouldPreserveRawError
1105
+ ? `DynamicWorkflow runner failed: ${errorName}: ${errorMessage}${
1106
+ errorStack ? `\n${errorStack}` : ''
1107
+ }`
1108
+ : `DynamicWorkflow runner failed: ${failure.message}`;
1110
1109
  const headers = new Headers({
1111
1110
  authorization: `Bearer ${executorToken}`,
1112
1111
  'content-type': 'application/json',
@@ -3283,6 +3282,32 @@ async function coordinatorRouteFetch(
3283
3282
  null,
3284
3283
  });
3285
3284
  }
3285
+ if (url.pathname === '/harness/probe') {
3286
+ const authError = authorizeCoordinatorControlRequest({ request, env });
3287
+ if (authError) return authError;
3288
+ try {
3289
+ const harness = await env.HARNESS.ping();
3290
+ return Response.json({
3291
+ ok: true,
3292
+ coordinatorDeployMarker: env.DEEPLINE_COORDINATOR_DEPLOY_MARKER ?? null,
3293
+ coordinatorRuntimeDeployVersion:
3294
+ env.CF_VERSION_METADATA?.id ??
3295
+ env.DEEPLINE_COORDINATOR_DEPLOY_MARKER ??
3296
+ null,
3297
+ harnessDeployMarker: harness.deployMarker,
3298
+ harnessRuntimeDeployVersion: harness.runtimeDeployVersion,
3299
+ harnessTs: harness.ts,
3300
+ });
3301
+ } catch (error) {
3302
+ return coordinatorRouteErrorResponse({
3303
+ logTag: '[coordinator.harness_probe.error]',
3304
+ code: 'COORDINATOR_HARNESS_PROBE_FAILED',
3305
+ phase: 'coordinator.harness_probe',
3306
+ runId: null,
3307
+ error,
3308
+ });
3309
+ }
3310
+ }
3286
3311
  if (url.pathname === '/staged-files/put') {
3287
3312
  const authError = authorizeCoordinatorControlRequest({ request, env });
3288
3313
  if (authError) return authError;
@@ -4188,22 +4188,10 @@ function createMinimalWorkerCtx(
4188
4188
  executedIndex: number;
4189
4189
  } => entry !== null,
4190
4190
  );
4191
- // Under the default isolation, every failed row persists as a
4192
- // recoverable `_status='failed'` row (it re-executes free next run).
4193
- // Under `onRowError: 'fail'` the run dies, so a failed row's partial
4194
- // data is persisted ONLY as a last-resort recovery: when this chunk has
4195
- // no other recoverable rows (no successful executed rows and no
4196
- // already-completed rows). That keeps a partial fail-fast run's export
4197
- // to the rows that fully committed before the failure, while an
4198
- // all-rows-failed fail-fast run still exposes the persisted partial
4199
- // cells instead of advertising an empty, unrecoverable dataset.
4200
- const failedRowsToPersist =
4201
- failFastRowErrors &&
4202
- (rowsToPersist.length > 0 ||
4203
- persistedExecutedIndexes.size > 0 ||
4204
- prepared.completedRows.length > 0)
4205
- ? []
4206
- : allFailedRowsToPersist;
4191
+ // Failed rows persist as recoverable `_status='failed'` rows in both
4192
+ // default row isolation and fail-fast mode. A fail-fast run still dies,
4193
+ // but export/retry keeps cells completed before the failing column.
4194
+ const failedRowsToPersist = allFailedRowsToPersist;
4207
4195
  if (rowsToPersist.length === 0 && failedRowsToPersist.length === 0) {
4208
4196
  return;
4209
4197
  }
@@ -4477,11 +4465,9 @@ function createMinimalWorkerCtx(
4477
4465
  Object.keys(cellMetaPatch).length > 0
4478
4466
  ? cellMetaPatch
4479
4467
  : undefined;
4480
- // Keep the partially-enriched row. Default isolation persists
4481
- // it as `_status='failed'` so the row can re-execute free on
4482
- // the next run. Fail-fast persists failed rows only after the
4483
- // chunk settles and only when every row failed; otherwise only
4484
- // fully committed successful rows are recoverable.
4468
+ // Keep the partially-enriched row. It persists as
4469
+ // `_status='failed'` so export/retry can recover cells that
4470
+ // completed before the row error.
4485
4471
  failedRowEntries[myIndex] = {
4486
4472
  row: enriched as T & Record<string, unknown>,
4487
4473
  error: message,
@@ -4501,7 +4487,7 @@ function createMinimalWorkerCtx(
4501
4487
  `Row ${absoluteIndex} of ctx.dataset("${name}") failed` +
4502
4488
  `${activeField ? ` at column "${activeField}"` : ''}: ${message} ` +
4503
4489
  (failFastRowErrors
4504
- ? '(row recorded as failed; onRowError:"fail" persists it only if every row fails)'
4490
+ ? '(row recorded as failed; onRowError:"fail" fails the run after recoverable cells persist)'
4505
4491
  : '(row recorded as failed; sibling rows continue and the row re-executes on the next run)'),
4506
4492
  ts: nowMs(),
4507
4493
  });
@@ -4896,12 +4882,11 @@ function createMinimalWorkerCtx(
4896
4882
  if (failFastRowErrors && totalRowsFailed > 0 && totalRowsWritten > 0) {
4897
4883
  // onRowError:'fail', PARTIAL failure (some rows committed): fail the run
4898
4884
  // without finalizing the dataset. The committed rows already persisted
4899
- // per chunk and are surfaced as a recovered dataset (the failed rows'
4900
- // partial data was intentionally NOT persisted here only the rows that
4901
- // fully committed before the failure are recoverable). We reach this
4902
- // AFTER the failing chunk completed normally (no per-row throw inside
4903
- // the durable chunk step, so no chunk-step retry storm); later chunks
4904
- // were skipped by the fail-fast short-circuit in the chunk loop.
4885
+ // per chunk and are surfaced as a recovered dataset alongside failed
4886
+ // rows' partial cells. We reach this AFTER the failing chunk completed
4887
+ // normally (no per-row throw inside the durable chunk step, so no
4888
+ // chunk-step retry storm); later chunks were skipped by the fail-fast
4889
+ // short-circuit in the chunk loop.
4905
4890
  const firstError = totalRowFailureSamples[0]?.error ?? 'unknown error';
4906
4891
  throw new Error(
4907
4892
  `ctx.dataset("${name}") failed for ${totalRowsFailed} executed row(s) under onRowError:'fail'. ` +
@@ -102,10 +102,10 @@ export const SDK_RELEASE = {
102
102
  // the SDK enrich generator's one-second stale policy.
103
103
  // 0.1.110 ships authored V2 prebuilts and required top-level play descriptions.
104
104
  // 0.1.111 ships dataset-native tool list getters and result row datasets.
105
- version: '0.1.151',
105
+ version: '0.1.153',
106
106
  apiContract: '2026-06-dataset-handle-results-hard-cutover',
107
107
  supportPolicy: {
108
- latest: '0.1.151',
108
+ latest: '0.1.153',
109
109
  minimumSupported: '0.1.53',
110
110
  deprecatedBelow: '0.1.53',
111
111
  commandMinimumSupported: [
@@ -2243,10 +2243,7 @@ export class PlayContextImpl {
2243
2243
  );
2244
2244
  } catch (error) {
2245
2245
  if (error instanceof FailFastMapRowsError) {
2246
- const rowsToPersist =
2247
- error.completedRows.length > 0
2248
- ? error.completedRows
2249
- : error.failedRows;
2246
+ const rowsToPersist = [...error.completedRows, ...error.failedRows];
2250
2247
  await incrementalPersistence?.flush();
2251
2248
  const unpersistedRows = incrementalPersistence
2252
2249
  ? rowsToPersist.filter(
@@ -1949,11 +1949,26 @@ async function readRuntimeRows(
1949
1949
  limit: number;
1950
1950
  offset: number;
1951
1951
  runId?: string | null;
1952
+ rowMode?: 'output' | 'all';
1952
1953
  sheetContract?: PlaySheetContract | null;
1953
1954
  },
1954
1955
  ): Promise<RuntimeApiRowRecord[]> {
1955
1956
  return await withRuntimePostgres(session, async (client) => {
1956
1957
  if (input.runId) {
1958
+ if (input.rowMode === 'all') {
1959
+ const { rows } = await client.query(
1960
+ `SELECT *
1961
+ FROM ${sheetTable(session)}
1962
+ WHERE _run_id = $1::text
1963
+ AND _status IN ('enriched', 'failed')
1964
+ ORDER BY _input_index ASC NULLS LAST, _created_at ASC, _key ASC
1965
+ LIMIT $2 OFFSET $3`,
1966
+ [input.runId, input.limit, input.offset],
1967
+ );
1968
+ return rows.map((raw) =>
1969
+ mapRuntimePostgresRow({ raw, sheetContract: input.sheetContract }),
1970
+ );
1971
+ }
1957
1972
  const { rows } = await client.query(
1958
1973
  `WITH scoped AS (
1959
1974
  SELECT *,
@@ -3618,6 +3633,7 @@ export async function readRuntimeSheetDatasetRows(
3618
3633
  input: {
3619
3634
  tableNamespace: string;
3620
3635
  runId?: string | null;
3636
+ rowMode?: 'output' | 'all';
3621
3637
  limit: number;
3622
3638
  offset: number;
3623
3639
  },
@@ -3646,6 +3662,7 @@ export async function readRuntimeSheetDatasetRows(
3646
3662
  limit,
3647
3663
  offset,
3648
3664
  runId: input.runId ?? null,
3665
+ rowMode: input.rowMode,
3649
3666
  });
3650
3667
  return {
3651
3668
  rows: rows.map((row) => row.data),
@@ -102,6 +102,14 @@ interface NeonModule {
102
102
  };
103
103
  }
104
104
 
105
+ function assertBindParams(params: unknown[] | undefined): void {
106
+ if (params !== undefined && !Array.isArray(params)) {
107
+ throw new Error(
108
+ 'Neon runtime query bind parameters must be an array. Configure Neon client options at client construction, not on query().',
109
+ );
110
+ }
111
+ }
112
+
105
113
  /**
106
114
  * Cached promise of the loaded Neon module. Once the first connect()
107
115
  * resolves, every subsequent connect on the same isolate hits this
@@ -126,13 +134,15 @@ function wrapNeonClient(client: NeonPoolClient): RuntimePoolClient {
126
134
  query: <R extends Record<string, unknown> = Record<string, unknown>>(
127
135
  text: string,
128
136
  params?: unknown[],
129
- ) =>
130
- (
137
+ ) => {
138
+ assertBindParams(params);
139
+ return (
131
140
  client.query as unknown as (
132
141
  t: string,
133
142
  p?: unknown[],
134
143
  ) => Promise<{ rows: R[] }>
135
- )(text, params),
144
+ )(text, params);
145
+ },
136
146
  release: () => {
137
147
  client.release();
138
148
  },
@@ -184,6 +194,7 @@ export function installNeonServerlessRuntimePoolDriver(): void {
184
194
  text: string,
185
195
  params?: unknown[],
186
196
  ) => {
197
+ assertBindParams(params);
187
198
  const sql = await getSql();
188
199
  return await sql.query<R>(text, params);
189
200
  },
package/dist/cli/index.js CHANGED
@@ -655,10 +655,10 @@ var SDK_RELEASE = {
655
655
  // the SDK enrich generator's one-second stale policy.
656
656
  // 0.1.110 ships authored V2 prebuilts and required top-level play descriptions.
657
657
  // 0.1.111 ships dataset-native tool list getters and result row datasets.
658
- version: "0.1.151",
658
+ version: "0.1.153",
659
659
  apiContract: "2026-06-dataset-handle-results-hard-cutover",
660
660
  supportPolicy: {
661
- latest: "0.1.151",
661
+ latest: "0.1.153",
662
662
  minimumSupported: "0.1.53",
663
663
  deprecatedBelow: "0.1.53",
664
664
  commandMinimumSupported: [
@@ -640,10 +640,10 @@ var SDK_RELEASE = {
640
640
  // the SDK enrich generator's one-second stale policy.
641
641
  // 0.1.110 ships authored V2 prebuilts and required top-level play descriptions.
642
642
  // 0.1.111 ships dataset-native tool list getters and result row datasets.
643
- version: "0.1.151",
643
+ version: "0.1.153",
644
644
  apiContract: "2026-06-dataset-handle-results-hard-cutover",
645
645
  supportPolicy: {
646
- latest: "0.1.151",
646
+ latest: "0.1.153",
647
647
  minimumSupported: "0.1.53",
648
648
  deprecatedBelow: "0.1.53",
649
649
  commandMinimumSupported: [
package/dist/index.js CHANGED
@@ -419,10 +419,10 @@ var SDK_RELEASE = {
419
419
  // the SDK enrich generator's one-second stale policy.
420
420
  // 0.1.110 ships authored V2 prebuilts and required top-level play descriptions.
421
421
  // 0.1.111 ships dataset-native tool list getters and result row datasets.
422
- version: "0.1.151",
422
+ version: "0.1.153",
423
423
  apiContract: "2026-06-dataset-handle-results-hard-cutover",
424
424
  supportPolicy: {
425
- latest: "0.1.151",
425
+ latest: "0.1.153",
426
426
  minimumSupported: "0.1.53",
427
427
  deprecatedBelow: "0.1.53",
428
428
  commandMinimumSupported: [
package/dist/index.mjs CHANGED
@@ -349,10 +349,10 @@ var SDK_RELEASE = {
349
349
  // the SDK enrich generator's one-second stale policy.
350
350
  // 0.1.110 ships authored V2 prebuilts and required top-level play descriptions.
351
351
  // 0.1.111 ships dataset-native tool list getters and result row datasets.
352
- version: "0.1.151",
352
+ version: "0.1.153",
353
353
  apiContract: "2026-06-dataset-handle-results-hard-cutover",
354
354
  supportPolicy: {
355
- latest: "0.1.151",
355
+ latest: "0.1.153",
356
356
  minimumSupported: "0.1.53",
357
357
  deprecatedBelow: "0.1.53",
358
358
  commandMinimumSupported: [
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "deepline",
3
- "version": "0.1.151",
3
+ "version": "0.1.153",
4
4
  "description": "Deepline SDK + CLI — B2B data enrichment powered by durable cloud execution",
5
5
  "license": "MIT",
6
6
  "repository": {