deepline 0.3.181 → 0.3.183

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.
@@ -200,7 +200,7 @@ export const SDK_RELEASE = {
200
200
  // getters keep their established compatibility behavior.
201
201
  // 0.3.1 deprecated the legacy `deepline enrich` command in favor of Plays.
202
202
  // 0.3.90 is the first deliberately versioned SDK release for API v3.
203
- version: '0.3.181',
203
+ version: '0.3.183',
204
204
  updateSummary:
205
205
  'Play grep now returns concise results with the matched fields and terms. Automatic CLI updates are enabled by default; use `deepline settings autoupdate off` to opt out, `deepline settings autoupdate on` to re-enable updates, or `deepline settings autoupdate pin <version>` to hold an exact release.',
206
206
  packageCapabilities: {
@@ -11836,6 +11836,9 @@ export async function failPostgresSchedulerAttempt(
11836
11836
  * Cancel a run: terminal `cancelled` status, all live attempts cancelled, and
11837
11837
  * terminal notify so observers settle immediately. An in-flight executor's
11838
11838
  * complete/fail then no-ops on its status guard (the run stays cancelled).
11839
+ * Receipt ownership is released by the terminal run status itself; claimers
11840
+ * lazily take an incomplete receipt from a terminal owner instead of making
11841
+ * cancellation rewrite an unbounded number of receipt rows.
11839
11842
  */
11840
11843
  export async function cancelPostgresSchedulerRun(
11841
11844
  client: PostgresSchedulerQueryClient,
@@ -11902,29 +11905,7 @@ export async function cancelPostgresSchedulerRun(
11902
11905
  WHERE target.run_id = $1
11903
11906
  AND target.status IN ('queued', 'running', 'waiting')
11904
11907
  ${strandedEligibility}
11905
- RETURNING target.run_id, target.org_id, target.launch_json
11906
- ),
11907
- released_receipts AS (
11908
- -- Cancellation is a terminal, and a terminal releases everything the
11909
- -- run claimed. A receipt left 'running' behind a dead lease matches no
11910
- -- non-forced claim status set, so a successor would park on it for the
11911
- -- whole receipt wait budget instead of executing the call itself.
11912
- UPDATE ${tableName('receipts', options)} AS receipt
11913
- SET ${RELEASE_RECEIPT_TO_PENDING_SET_CLAUSE}
11914
- FROM cancelled_run
11915
- WHERE receipt.org_id = cancelled_run.org_id
11916
- AND receipt.status IN ('queued', 'running')
11917
- -- Every successful claim stamps both run_id and
11918
- -- lease_owner_run_id with the current owner. Keep the explicit
11919
- -- owner fence below for mixed-version rows, while giving Postgres
11920
- -- the direct run_id equality it needs to use
11921
- -- runtime_scheduler_receipts_run_idx. Without this predicate,
11922
- -- COALESCE forces a scan of the org's complete receipt history and
11923
- -- cancellation can hit its statement timeout on a large workspace.
11924
- AND receipt.run_id = cancelled_run.run_id
11925
- AND COALESCE(receipt.lease_owner_run_id, receipt.run_id)
11926
- = cancelled_run.run_id
11927
- RETURNING receipt.k
11908
+ RETURNING target.run_id, target.launch_json
11928
11909
  ),
11929
11910
  cancelled_attempts AS (
11930
11911
  UPDATE ${tableName('attempts', options)}
@@ -13126,6 +13107,22 @@ function postgresSchedulerReceiptLeaseId(input: {
13126
13107
  : null;
13127
13108
  }
13128
13109
 
13110
+ function postgresSchedulerReceiptOwnerIsTerminalSql(
13111
+ receiptTableReference: string,
13112
+ options?: Pick<PostgresSchedulerOptions, 'schema'>,
13113
+ ): string {
13114
+ return `EXISTS (
13115
+ SELECT 1
13116
+ FROM ${tableName('runs', options)} AS receipt_owner_run
13117
+ WHERE receipt_owner_run.run_id = COALESCE(
13118
+ ${receiptTableReference}.lease_owner_run_id,
13119
+ ${receiptTableReference}.run_id
13120
+ )
13121
+ AND receipt_owner_run.org_id = ${receiptTableReference}.org_id
13122
+ AND receipt_owner_run.status IN ('completed', 'failed', 'cancelled')
13123
+ )`;
13124
+ }
13125
+
13129
13126
  function mapReceiptRow(row: ReceiptRow): RuntimeStepReceipt {
13130
13127
  const leaseExpiresAt = row.lease_expires_at;
13131
13128
  const outputRef = isRuntimeReceiptValueReference(row.output_ref)
@@ -13429,6 +13426,11 @@ export async function claimPostgresSchedulerReceipt(
13429
13426
  );
13430
13427
  const leaseId =
13431
13428
  input.leaseId?.trim() || postgresSchedulerReceiptLeaseId(input);
13429
+ const receiptTable = tableName('receipts', options);
13430
+ const ownerIsTerminal = postgresSchedulerReceiptOwnerIsTerminalSql(
13431
+ receiptTable,
13432
+ options,
13433
+ );
13432
13434
  const result = await client.query<ReceiptRow & { claim_state: string }>(
13433
13435
  `
13434
13436
  WITH terminal AS (
@@ -13436,14 +13438,14 @@ export async function claimPostgresSchedulerReceipt(
13436
13438
  -- explicitly forces refresh. Read them before the UPSERT so popular
13437
13439
  -- prebuilt keys do not take a conflicting-row lock or create WAL.
13438
13440
  SELECT k, status, output_json, output_ref, error, error_payload, failure_kind, run_id, lease_id, lease_owner_run_id, lease_owner_attempt, lease_expires_at
13439
- FROM ${tableName('receipts', options)}
13441
+ FROM ${receiptTable}
13440
13442
  WHERE org_id = $9
13441
13443
  AND k = $1
13442
13444
  AND status IN ('completed', 'skipped')
13443
13445
  AND ($7::boolean IS NOT TRUE OR run_id = $2)
13444
13446
  ),
13445
13447
  claimed AS (
13446
- INSERT INTO ${tableName('receipts', options)} (
13448
+ INSERT INTO ${receiptTable} (
13447
13449
  org_id,
13448
13450
  k,
13449
13451
  status,
@@ -13484,33 +13486,45 @@ export async function claimPostgresSchedulerReceipt(
13484
13486
  error_payload = NULL,
13485
13487
  failure_kind = 0,
13486
13488
  updated_at = now()
13487
- WHERE ${tableName('receipts', options)}.status = ANY($3::text[])
13488
- AND ${tableName('receipts', options)}.org_id = $9
13489
+ WHERE ${receiptTable}.status = ANY($3::text[])
13490
+ AND ${receiptTable}.org_id = $9
13489
13491
  AND (
13490
- ${tableName('receipts', options)}.status <> 'failed'
13492
+ ${receiptTable}.status <> 'failed'
13491
13493
  OR $7::boolean
13492
13494
  OR $8::boolean
13493
- OR ${tableName('receipts', options)}.run_id IS DISTINCT FROM $2
13495
+ OR ${receiptTable}.run_id IS DISTINCT FROM $2
13494
13496
  )
13495
13497
  AND (
13496
- ${tableName('receipts', options)}.status = 'failed'
13497
- OR ${tableName('receipts', options)}.lease_id IS NULL
13498
- AND ${tableName('receipts', options)}.lease_expires_at IS NULL
13499
- OR ${tableName('receipts', options)}.lease_expires_at <= now()
13498
+ (
13499
+ ${receiptTable}.status IN ('queued', 'running')
13500
+ AND ${ownerIsTerminal}
13501
+ )
13500
13502
  OR (
13501
- -- Billed-implies-durable: a higher scheduler invocation must never
13502
- -- steal a live work-receipt lease while the prior invocation may
13503
- -- still be inside a provider call. Same-run reclaims are allowed
13504
- -- only after the lease TTL proves the prior attempt is dead.
13505
- ${tableName('receipts', options)}.lease_id IS NOT NULL
13506
- AND ${tableName('receipts', options)}.lease_expires_at IS NOT NULL
13507
- AND ${tableName('receipts', options)}.lease_expires_at <= now()
13508
- AND
13509
- COALESCE(
13510
- ${tableName('receipts', options)}.lease_owner_run_id,
13511
- ${tableName('receipts', options)}.run_id
13512
- ) = $2
13513
- AND COALESCE(${tableName('receipts', options)}.lease_owner_attempt, 0) < $5::integer
13503
+ (
13504
+ ${receiptTable}.status NOT IN ('queued', 'running')
13505
+ OR $10::boolean
13506
+ )
13507
+ AND (
13508
+ ${receiptTable}.status = 'failed'
13509
+ OR ${receiptTable}.lease_id IS NULL
13510
+ AND ${receiptTable}.lease_expires_at IS NULL
13511
+ OR ${receiptTable}.lease_expires_at <= now()
13512
+ OR (
13513
+ -- Billed-implies-durable: a higher scheduler invocation must never
13514
+ -- steal a live work-receipt lease while the prior invocation may
13515
+ -- still be inside a provider call. Same-run reclaims are allowed
13516
+ -- only after the lease TTL proves the prior attempt is dead.
13517
+ ${receiptTable}.lease_id IS NOT NULL
13518
+ AND ${receiptTable}.lease_expires_at IS NOT NULL
13519
+ AND ${receiptTable}.lease_expires_at <= now()
13520
+ AND
13521
+ COALESCE(
13522
+ ${receiptTable}.lease_owner_run_id,
13523
+ ${receiptTable}.run_id
13524
+ ) = $2
13525
+ AND COALESCE(${receiptTable}.lease_owner_attempt, 0) < $5::integer
13526
+ )
13527
+ )
13514
13528
  )
13515
13529
  )
13516
13530
  RETURNING k, status, output_json, output_ref, error, error_payload, failure_kind, run_id, lease_id, lease_owner_run_id, lease_owner_attempt, lease_expires_at
@@ -13530,13 +13544,14 @@ export async function claimPostgresSchedulerReceipt(
13530
13544
  ? ['pending', 'failed', 'running', 'completed', 'skipped']
13531
13545
  : input.reclaimRunning
13532
13546
  ? ['pending', 'failed', 'running']
13533
- : ['pending', 'failed'],
13547
+ : ['pending', 'failed', 'queued', 'running'],
13534
13548
  leaseId,
13535
13549
  runAttempt,
13536
13550
  PLAY_RUNTIME_WORK_RECEIPT_LEASE_TTL_MS,
13537
13551
  input.forceRefresh === true,
13538
13552
  input.forceFailedRefresh === true,
13539
13553
  receiptOrgId(options),
13554
+ input.forceRefresh === true || input.reclaimRunning === true,
13540
13555
  ],
13541
13556
  );
13542
13557
  if (result.rows[0]) {
@@ -13581,6 +13596,11 @@ export async function claimPostgresSchedulerReceipts(
13581
13596
  const providedLeaseId = input.leaseIds?.[index]?.trim();
13582
13597
  return providedLeaseId || postgresSchedulerReceiptLeaseId(input);
13583
13598
  });
13599
+ const receiptTable = tableName('receipts', options);
13600
+ const ownerIsTerminal = postgresSchedulerReceiptOwnerIsTerminalSql(
13601
+ receiptTable,
13602
+ options,
13603
+ );
13584
13604
  const result = await client.query<ReceiptRow & { claim_state?: string }>(
13585
13605
  `
13586
13606
  WITH inputs AS (
@@ -13608,7 +13628,7 @@ export async function claimPostgresSchedulerReceipts(
13608
13628
  receipt.lease_expires_at,
13609
13629
  inputs.ord
13610
13630
  FROM inputs
13611
- JOIN ${tableName('receipts', options)} AS receipt
13631
+ JOIN ${receiptTable} AS receipt
13612
13632
  ON receipt.org_id = $10
13613
13633
  AND receipt.k = inputs.k
13614
13634
  WHERE receipt.status IN ('completed', 'skipped')
@@ -13628,7 +13648,7 @@ export async function claimPostgresSchedulerReceipts(
13628
13648
  ORDER BY inputs.k, inputs.ord
13629
13649
  ),
13630
13650
  claimed AS (
13631
- INSERT INTO ${tableName('receipts', options)} (
13651
+ INSERT INTO ${receiptTable} (
13632
13652
  org_id,
13633
13653
  k,
13634
13654
  status,
@@ -13668,19 +13688,31 @@ export async function claimPostgresSchedulerReceipts(
13668
13688
  error_payload = NULL,
13669
13689
  failure_kind = 0,
13670
13690
  updated_at = now()
13671
- WHERE ${tableName('receipts', options)}.status = ANY($3::text[])
13672
- AND ${tableName('receipts', options)}.org_id = $10
13691
+ WHERE ${receiptTable}.status = ANY($3::text[])
13692
+ AND ${receiptTable}.org_id = $10
13673
13693
  AND (
13674
- ${tableName('receipts', options)}.status <> 'failed'
13694
+ ${receiptTable}.status <> 'failed'
13675
13695
  OR $7::boolean
13676
13696
  OR $8::boolean
13677
- OR ${tableName('receipts', options)}.run_id IS DISTINCT FROM $2
13697
+ OR ${receiptTable}.run_id IS DISTINCT FROM $2
13678
13698
  )
13679
13699
  AND (
13680
- ${tableName('receipts', options)}.status = 'failed'
13681
- OR ${tableName('receipts', options)}.lease_id IS NULL
13682
- AND ${tableName('receipts', options)}.lease_expires_at IS NULL
13683
- OR ${tableName('receipts', options)}.lease_expires_at <= now()
13700
+ (
13701
+ ${receiptTable}.status IN ('queued', 'running')
13702
+ AND ${ownerIsTerminal}
13703
+ )
13704
+ OR (
13705
+ (
13706
+ ${receiptTable}.status NOT IN ('queued', 'running')
13707
+ OR $11::boolean
13708
+ )
13709
+ AND (
13710
+ ${receiptTable}.status = 'failed'
13711
+ OR ${receiptTable}.lease_id IS NULL
13712
+ AND ${receiptTable}.lease_expires_at IS NULL
13713
+ OR ${receiptTable}.lease_expires_at <= now()
13714
+ )
13715
+ )
13684
13716
  )
13685
13717
  RETURNING k, status, output_json, output_ref, error, error_payload, failure_kind, run_id, lease_id, lease_owner_run_id, lease_owner_attempt, lease_expires_at
13686
13718
  ),
@@ -13703,7 +13735,7 @@ export async function claimPostgresSchedulerReceipts(
13703
13735
  AS replayed_claim,
13704
13736
  inputs.ord
13705
13737
  FROM inputs
13706
- JOIN ${tableName('receipts', options)} AS receipt
13738
+ JOIN ${receiptTable} AS receipt
13707
13739
  ON receipt.org_id = $10
13708
13740
  AND receipt.k = inputs.k
13709
13741
  WHERE (
@@ -13801,7 +13833,7 @@ export async function claimPostgresSchedulerReceipts(
13801
13833
  ? ['pending', 'failed', 'running', 'completed', 'skipped']
13802
13834
  : input.reclaimRunning
13803
13835
  ? ['pending', 'failed', 'running']
13804
- : ['pending', 'failed'],
13836
+ : ['pending', 'failed', 'queued', 'running'],
13805
13837
  leaseIds,
13806
13838
  runAttempt,
13807
13839
  PLAY_RUNTIME_WORK_RECEIPT_LEASE_TTL_MS,
@@ -13809,6 +13841,7 @@ export async function claimPostgresSchedulerReceipts(
13809
13841
  input.forceFailedRefresh === true,
13810
13842
  input.forceRefresh === true,
13811
13843
  receiptOrgId(options),
13844
+ input.forceRefresh === true || input.reclaimRunning === true,
13812
13845
  ],
13813
13846
  );
13814
13847
  return result.rows.map((row) =>
@@ -14510,10 +14543,9 @@ export async function releasePostgresSchedulerReceipt(
14510
14543
  }
14511
14544
 
14512
14545
  /**
14513
- * The write that returns a claimed receipt to the free pool. Every release
14514
- * path shares it so a successor's non-forced claim — whose status set is
14515
- * `('pending','failed')` and whose lease guard requires no live lease — always
14516
- * matches what a dead owner left behind.
14546
+ * The write that returns one attempt's claimed receipts to the free pool.
14547
+ * Attempt cleanup uses this eager path; whole-run terminalization is the
14548
+ * constant-time ownership fence that claimers resolve lazily.
14517
14549
  */
14518
14550
  const RELEASE_RECEIPT_TO_PENDING_SET_CLAUSE = `status = 'pending',
14519
14551
  output_json = NULL,
package/dist/cli/index.js CHANGED
@@ -3051,7 +3051,7 @@ var SDK_RELEASE = {
3051
3051
  // getters keep their established compatibility behavior.
3052
3052
  // 0.3.1 deprecated the legacy `deepline enrich` command in favor of Plays.
3053
3053
  // 0.3.90 is the first deliberately versioned SDK release for API v3.
3054
- version: "0.3.181",
3054
+ version: "0.3.183",
3055
3055
  updateSummary: "Play grep now returns concise results with the matched fields and terms. Automatic CLI updates are enabled by default; use `deepline settings autoupdate off` to opt out, `deepline settings autoupdate on` to re-enable updates, or `deepline settings autoupdate pin <version>` to hold an exact release.",
3056
3056
  packageCapabilities: {
3057
3057
  updatePreferences: 1
@@ -3046,7 +3046,7 @@ var SDK_RELEASE = {
3046
3046
  // getters keep their established compatibility behavior.
3047
3047
  // 0.3.1 deprecated the legacy `deepline enrich` command in favor of Plays.
3048
3048
  // 0.3.90 is the first deliberately versioned SDK release for API v3.
3049
- version: "0.3.181",
3049
+ version: "0.3.183",
3050
3050
  updateSummary: "Play grep now returns concise results with the matched fields and terms. Automatic CLI updates are enabled by default; use `deepline settings autoupdate off` to opt out, `deepline settings autoupdate on` to re-enable updates, or `deepline settings autoupdate pin <version>` to hold an exact release.",
3051
3051
  packageCapabilities: {
3052
3052
  updatePreferences: 1
package/dist/index.js CHANGED
@@ -864,7 +864,7 @@ var SDK_RELEASE = {
864
864
  // getters keep their established compatibility behavior.
865
865
  // 0.3.1 deprecated the legacy `deepline enrich` command in favor of Plays.
866
866
  // 0.3.90 is the first deliberately versioned SDK release for API v3.
867
- version: "0.3.181",
867
+ version: "0.3.183",
868
868
  updateSummary: "Play grep now returns concise results with the matched fields and terms. Automatic CLI updates are enabled by default; use `deepline settings autoupdate off` to opt out, `deepline settings autoupdate on` to re-enable updates, or `deepline settings autoupdate pin <version>` to hold an exact release.",
869
869
  packageCapabilities: {
870
870
  updatePreferences: 1
package/dist/index.mjs CHANGED
@@ -768,7 +768,7 @@ var SDK_RELEASE = {
768
768
  // getters keep their established compatibility behavior.
769
769
  // 0.3.1 deprecated the legacy `deepline enrich` command in favor of Plays.
770
770
  // 0.3.90 is the first deliberately versioned SDK release for API v3.
771
- version: "0.3.181",
771
+ version: "0.3.183",
772
772
  updateSummary: "Play grep now returns concise results with the matched fields and terms. Automatic CLI updates are enabled by default; use `deepline settings autoupdate off` to opt out, `deepline settings autoupdate on` to re-enable updates, or `deepline settings autoupdate pin <version>` to hold an exact release.",
773
773
  packageCapabilities: {
774
774
  updatePreferences: 1
@@ -149,7 +149,7 @@ type SdkRelease = {
149
149
  supportPolicy: SdkSupportPolicy;
150
150
  };
151
151
  declare const SDK_RELEASE: {
152
- readonly version: "0.3.181";
152
+ readonly version: "0.3.183";
153
153
  readonly updateSummary: "Play grep now returns concise results with the matched fields and terms. Automatic CLI updates are enabled by default; use `deepline settings autoupdate off` to opt out, `deepline settings autoupdate on` to re-enable updates, or `deepline settings autoupdate pin <version>` to hold an exact release.";
154
154
  readonly packageCapabilities: {
155
155
  readonly updatePreferences: 1;
package/dist/release.d.ts CHANGED
@@ -149,7 +149,7 @@ type SdkRelease = {
149
149
  supportPolicy: SdkSupportPolicy;
150
150
  };
151
151
  declare const SDK_RELEASE: {
152
- readonly version: "0.3.181";
152
+ readonly version: "0.3.183";
153
153
  readonly updateSummary: "Play grep now returns concise results with the matched fields and terms. Automatic CLI updates are enabled by default; use `deepline settings autoupdate off` to opt out, `deepline settings autoupdate on` to re-enable updates, or `deepline settings autoupdate pin <version>` to hold an exact release.";
154
154
  readonly packageCapabilities: {
155
155
  readonly updatePreferences: 1;
package/dist/release.js CHANGED
@@ -74,7 +74,7 @@ var SDK_RELEASE = {
74
74
  // getters keep their established compatibility behavior.
75
75
  // 0.3.1 deprecated the legacy `deepline enrich` command in favor of Plays.
76
76
  // 0.3.90 is the first deliberately versioned SDK release for API v3.
77
- version: "0.3.181",
77
+ version: "0.3.183",
78
78
  updateSummary: "Play grep now returns concise results with the matched fields and terms. Automatic CLI updates are enabled by default; use `deepline settings autoupdate off` to opt out, `deepline settings autoupdate on` to re-enable updates, or `deepline settings autoupdate pin <version>` to hold an exact release.",
79
79
  packageCapabilities: {
80
80
  updatePreferences: 1
package/dist/release.mjs CHANGED
@@ -48,7 +48,7 @@ var SDK_RELEASE = {
48
48
  // getters keep their established compatibility behavior.
49
49
  // 0.3.1 deprecated the legacy `deepline enrich` command in favor of Plays.
50
50
  // 0.3.90 is the first deliberately versioned SDK release for API v3.
51
- version: "0.3.181",
51
+ version: "0.3.183",
52
52
  updateSummary: "Play grep now returns concise results with the matched fields and terms. Automatic CLI updates are enabled by default; use `deepline settings autoupdate off` to opt out, `deepline settings autoupdate on` to re-enable updates, or `deepline settings autoupdate pin <version>` to hold an exact release.",
53
53
  packageCapabilities: {
54
54
  updatePreferences: 1
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "deepline",
3
- "version": "0.3.181",
3
+ "version": "0.3.183",
4
4
  "description": "GTM data CLI and TypeScript SDK for coding agents",
5
5
  "license": "MIT",
6
6
  "homepage": "https://code.deepline.com",