deepline 0.1.174 → 0.1.176

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.
@@ -2224,7 +2224,10 @@ async function prepareRuntimeSheetDatasetRows(
2224
2224
  normalizedTableNamespace: string;
2225
2225
  physicalInsertColumnsSql: string;
2226
2226
  physicalInsertValuesSql: string;
2227
+ physicalRefreshSetSql: string;
2228
+ physicalUpsertSetSql: string;
2227
2229
  outputPhysicalColumns: PhysicalSheetColumnProjection[];
2230
+ force?: boolean;
2228
2231
  },
2229
2232
  ): Promise<{ inserted: number; pendingKeys: string[] }> {
2230
2233
  let inserted = 0;
@@ -2259,10 +2262,14 @@ async function prepareRuntimeSheetDatasetRows(
2259
2262
  UPDATE ${sheetTable(session)} AS target
2260
2263
  SET _input_index = input_rows._input_index,
2261
2264
  _updated_at = now(),
2262
- _version = ${nextRuntimeSheetVersionExpression(session)}
2265
+ _version = ${nextRuntimeSheetVersionExpression(session)}${input.physicalRefreshSetSql}
2263
2266
  FROM input_rows
2264
2267
  WHERE target._key = input_rows._key
2265
- AND target._input_index IS DISTINCT FROM input_rows._input_index
2268
+ AND target._status <> 'stale'
2269
+ AND (
2270
+ $7::boolean
2271
+ OR target._input_index IS DISTINCT FROM input_rows._input_index
2272
+ )
2266
2273
  RETURNING target._key
2267
2274
  ),
2268
2275
  inserted_rows AS (
@@ -2274,7 +2281,7 @@ async function prepareRuntimeSheetDatasetRows(
2274
2281
  _run_id = EXCLUDED._run_id,
2275
2282
  _input_index = EXCLUDED._input_index,
2276
2283
  _updated_at = now(),
2277
- _version = ${nextRuntimeSheetVersionExpression(session)}
2284
+ _version = ${nextRuntimeSheetVersionExpression(session)}${input.physicalUpsertSetSql}
2278
2285
  WHERE ${sheetTable(session)}._status = 'stale'
2279
2286
  RETURNING _key
2280
2287
  ),
@@ -2375,6 +2382,7 @@ async function prepareRuntimeSheetDatasetRows(
2375
2382
  input.runId,
2376
2383
  input.normalizedPlayName,
2377
2384
  input.normalizedTableNamespace,
2385
+ input.force === true,
2378
2386
  ],
2379
2387
  );
2380
2388
  inserted += Number(rows[0]?.inserted_count ?? 0);
@@ -2398,30 +2406,35 @@ async function buildRuntimeSheetDatasetStartResult(
2398
2406
  runId: string;
2399
2407
  inserted: number;
2400
2408
  pendingKeys: string[];
2409
+ force?: boolean;
2401
2410
  timings?: RuntimeSheetTiming[];
2402
2411
  },
2403
2412
  ): Promise<PrepareRuntimeSheetResult> {
2413
+ const datasetFields = input.sheetContract.columns.flatMap((column) =>
2414
+ column.source === 'datasetColumn' && typeof column.field === 'string'
2415
+ ? [column.field]
2416
+ : [],
2417
+ );
2418
+ const buildFreshPendingRows = () => {
2419
+ return input.rowEntries.map((entry) => {
2420
+ const row: Record<string, unknown> = {
2421
+ ...sanitizePostgresJsonValue(entry.row),
2422
+ __deeplineRowKey: entry.key,
2423
+ };
2424
+ for (const field of datasetFields) {
2425
+ if (!Object.prototype.hasOwnProperty.call(row, field)) {
2426
+ row[field] = null;
2427
+ }
2428
+ }
2429
+ return row;
2430
+ });
2431
+ };
2432
+
2404
2433
  if (input.inserted === input.rowEntries.length) {
2405
- const datasetFields = input.sheetContract.columns.flatMap((column) =>
2406
- column.source === 'datasetColumn' && typeof column.field === 'string'
2407
- ? [column.field]
2408
- : [],
2409
- );
2410
2434
  return {
2411
2435
  inserted: input.inserted,
2412
2436
  skipped: input.sourceRowsLength - input.rowEntries.length,
2413
- pendingRows: input.rowEntries.map((entry) => {
2414
- const row: Record<string, unknown> = {
2415
- ...sanitizePostgresJsonValue(entry.row),
2416
- __deeplineRowKey: entry.key,
2417
- };
2418
- for (const field of datasetFields) {
2419
- if (!Object.prototype.hasOwnProperty.call(row, field)) {
2420
- row[field] = null;
2421
- }
2422
- }
2423
- return row;
2424
- }),
2437
+ pendingRows: buildFreshPendingRows(),
2425
2438
  completedRows: [],
2426
2439
  tableNamespace: input.tableNamespace,
2427
2440
  };
@@ -2434,7 +2447,24 @@ async function buildRuntimeSheetDatasetStartResult(
2434
2447
  runId: input.runId,
2435
2448
  normalizedPlayName: input.normalizedPlayName,
2436
2449
  normalizedTableNamespace: input.normalizedTableNamespace,
2450
+ outputFields: input.force === true ? datasetFields : [],
2437
2451
  });
2452
+ if (pendingKeys.size > 0) {
2453
+ input.timings?.push({
2454
+ phase: 'mark_rows_pending_for_recompute',
2455
+ ms: Date.now() - startedAt,
2456
+ rows: pendingKeys.size,
2457
+ });
2458
+ }
2459
+ if (input.force === true) {
2460
+ return {
2461
+ inserted: input.inserted,
2462
+ skipped: input.sourceRowsLength - input.rowEntries.length,
2463
+ pendingRows: buildFreshPendingRows(),
2464
+ completedRows: [],
2465
+ tableNamespace: input.tableNamespace,
2466
+ };
2467
+ }
2438
2468
  const persistedRows = await readRuntimeRowsByKey(
2439
2469
  client,
2440
2470
  session,
@@ -2444,13 +2474,6 @@ async function buildRuntimeSheetDatasetStartResult(
2444
2474
  const persistedRowsByKey = new Map(
2445
2475
  persistedRows.map((row) => [row.key, row.data]),
2446
2476
  );
2447
- if (pendingKeys.size > 0) {
2448
- input.timings?.push({
2449
- phase: 'mark_rows_pending_for_recompute',
2450
- ms: Date.now() - startedAt,
2451
- rows: pendingKeys.size,
2452
- });
2453
- }
2454
2477
  const buildMergedRow = (entry: RuntimeDatasetRowEntry) => {
2455
2478
  const merged = { ...entry.row };
2456
2479
  for (const [field, value] of Object.entries(
@@ -2489,12 +2512,14 @@ async function markRuntimeRowsPendingForRecompute(
2489
2512
  runId: string;
2490
2513
  normalizedPlayName: string;
2491
2514
  normalizedTableNamespace: string;
2515
+ outputFields?: string[];
2492
2516
  },
2493
2517
  ): Promise<void> {
2494
2518
  if (input.keys.length === 0) return;
2519
+ const outputFields = [...new Set(input.outputFields ?? [])];
2495
2520
  await client.query(
2496
2521
  `WITH target_rows AS (
2497
- SELECT _key, _status
2522
+ SELECT _key, _status, _cell_meta
2498
2523
  FROM ${sheetTable(session)}
2499
2524
  WHERE _key = ANY($1::text[])
2500
2525
  FOR UPDATE
@@ -2511,7 +2536,8 @@ async function markRuntimeRowsPendingForRecompute(
2511
2536
  target._status <> 'pending'
2512
2537
  OR target._run_id IS DISTINCT FROM $2::text
2513
2538
  )
2514
- RETURNING target_rows._status AS previous_status
2539
+ RETURNING target_rows._status AS previous_status,
2540
+ target_rows._cell_meta AS previous_cell_meta
2515
2541
  ),
2516
2542
  summary_counts AS (
2517
2543
  SELECT
@@ -2520,6 +2546,18 @@ async function markRuntimeRowsPendingForRecompute(
2520
2546
  count(*) FILTER (WHERE previous_status = 'running')::int AS running_to_pending
2521
2547
  FROM updated
2522
2548
  ),
2549
+ column_delta_counts AS (
2550
+ SELECT field_values.field,
2551
+ count(*) FILTER (
2552
+ WHERE previous_cell_meta -> field_values.field ->> 'status' = 'completed'
2553
+ )::int AS completed_to_pending,
2554
+ count(*) FILTER (
2555
+ WHERE previous_cell_meta -> field_values.field ->> 'status' = 'failed'
2556
+ )::int AS failed_to_pending
2557
+ FROM updated
2558
+ JOIN unnest($5::text[]) AS field_values(field) ON true
2559
+ GROUP BY field_values.field
2560
+ ),
2523
2561
  summary_delta AS (
2524
2562
  INSERT INTO ${summaryTable(session)} AS target (play_name, table_namespace, total, queued, running, completed, failed)
2525
2563
  SELECT
@@ -2547,6 +2585,27 @@ async function markRuntimeRowsPendingForRecompute(
2547
2585
  })},
2548
2586
  _updated_at = now()
2549
2587
  RETURNING 1
2588
+ ),
2589
+ column_summary_delta AS (
2590
+ INSERT INTO ${columnSummaryTable(session)} AS target (
2591
+ play_name,
2592
+ table_namespace,
2593
+ field,
2594
+ completed,
2595
+ failed
2596
+ )
2597
+ SELECT $3::text,
2598
+ $4::text,
2599
+ field,
2600
+ -completed_to_pending,
2601
+ -failed_to_pending
2602
+ FROM column_delta_counts
2603
+ WHERE completed_to_pending > 0 OR failed_to_pending > 0
2604
+ ON CONFLICT (play_name, table_namespace, field) DO UPDATE SET
2605
+ completed = GREATEST(target.completed + EXCLUDED.completed, 0),
2606
+ failed = GREATEST(target.failed + EXCLUDED.failed, 0),
2607
+ _updated_at = now()
2608
+ RETURNING 1
2550
2609
  )
2551
2610
  SELECT 1`,
2552
2611
  [
@@ -2554,6 +2613,7 @@ async function markRuntimeRowsPendingForRecompute(
2554
2613
  input.runId,
2555
2614
  input.normalizedPlayName,
2556
2615
  input.normalizedTableNamespace,
2616
+ outputFields,
2557
2617
  ],
2558
2618
  );
2559
2619
  }
@@ -3237,6 +3297,7 @@ export async function startRuntimeSheetDataset(
3237
3297
  rows: Record<string, unknown>[];
3238
3298
  runId: string;
3239
3299
  inputOffset?: number;
3300
+ force?: boolean;
3240
3301
  },
3241
3302
  ): Promise<PrepareRuntimeSheetResult> {
3242
3303
  const totalStartedAt = Date.now();
@@ -3334,6 +3395,24 @@ export async function startRuntimeSheetDataset(
3334
3395
  .map((column) => `payload -> ${quoteLiteral(column)}`)
3335
3396
  .join(', ')}`
3336
3397
  : '';
3398
+ const physicalRefreshSetSql =
3399
+ physicalColumns.length > 0
3400
+ ? `, ${physicalColumns
3401
+ .map(
3402
+ (column) =>
3403
+ `${quoteIdentifier(column)} = input_rows.payload -> ${quoteLiteral(column)}`,
3404
+ )
3405
+ .join(', ')}`
3406
+ : '';
3407
+ const physicalUpsertSetSql =
3408
+ physicalColumns.length > 0
3409
+ ? `, ${physicalColumns
3410
+ .map(
3411
+ (column) =>
3412
+ `${quoteIdentifier(column)} = EXCLUDED.${quoteIdentifier(column)}`,
3413
+ )
3414
+ .join(', ')}`
3415
+ : '';
3337
3416
  const outputPhysicalColumns = outputPhysicalSheetColumnProjections(
3338
3417
  input.sheetContract,
3339
3418
  );
@@ -3364,15 +3443,26 @@ export async function startRuntimeSheetDataset(
3364
3443
  normalizedTableNamespace,
3365
3444
  physicalInsertColumnsSql,
3366
3445
  physicalInsertValuesSql,
3446
+ physicalRefreshSetSql:
3447
+ input.force === true ? physicalRefreshSetSql : '',
3448
+ physicalUpsertSetSql,
3367
3449
  outputPhysicalColumns,
3450
+ force: input.force === true,
3368
3451
  });
3452
+ const effectivePrepared = input.force
3453
+ ? {
3454
+ inserted: prepared.inserted,
3455
+ pendingKeys: rowEntries.map((entry) => entry.key),
3456
+ }
3457
+ : prepared;
3369
3458
  timings.push({
3370
3459
  phase: 'prepare_rows_sql',
3371
3460
  ms: Date.now() - prepareStartedAt,
3372
3461
  rows: rowEntries.length,
3373
3462
  chunks: chunks.length,
3374
- inserted: prepared.inserted,
3375
- pending: prepared.pendingKeys.length,
3463
+ inserted: effectivePrepared.inserted,
3464
+ pending: effectivePrepared.pendingKeys.length,
3465
+ ...(input.force ? { force: true } : {}),
3376
3466
  });
3377
3467
  const buildStartedAt = Date.now();
3378
3468
  const built = await buildRuntimeSheetDatasetStartResult(client, session, {
@@ -3384,7 +3474,8 @@ export async function startRuntimeSheetDataset(
3384
3474
  normalizedTableNamespace,
3385
3475
  runId: input.runId,
3386
3476
  timings,
3387
- ...prepared,
3477
+ force: input.force === true,
3478
+ ...effectivePrepared,
3388
3479
  });
3389
3480
  timings.push({
3390
3481
  phase: 'build_result',
@@ -83,6 +83,8 @@ export type PlaySchedulerSubmitInput = {
83
83
  artifactHash: string;
84
84
  graphHash: string;
85
85
  input: Record<string, unknown>;
86
+ /** Run-level --force cache bypass for dataset rows and ctx.tools.execute receipts. */
87
+ forceToolRefresh?: boolean | null;
86
88
  inputFile?: {
87
89
  name?: string;
88
90
  path?: string;