deepline 0.1.290 → 0.1.291

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.
@@ -155,7 +155,7 @@ export const SDK_RELEASE = {
155
155
  // 0.1.253 makes play-page browser opening opt-in and retires --no-open.
156
156
  // 0.1.254 removes the internal operations tree from the published SDK CLI.
157
157
  // Operators use the checkout-local deepline-admin binary instead.
158
- version: '0.1.290',
158
+ version: '0.1.291',
159
159
  contracts: {
160
160
  api: {
161
161
  name: 'sdk-http-api',
@@ -358,6 +358,7 @@ type RuntimeApiRequest =
358
358
  export type WorkerRuntimeApiContext = {
359
359
  baseUrl: string;
360
360
  executorToken: string;
361
+ boundary?: 'app_runtime' | 'receipt_gateway';
361
362
  integrationMode?: 'live' | 'eval_stub' | 'fixture' | null;
362
363
  vercelProtectionBypassToken?: string | null;
363
364
  runtimeTestFaultHeader?: string | null;
@@ -874,6 +875,7 @@ async function retryAppRuntimeBodyTimeoutOrThrow(input: {
874
875
  attemptStartedAt: number;
875
876
  httpStatus?: number;
876
877
  retryAfterMs?: number | null;
878
+ boundaryLabel: string;
877
879
  }): Promise<void> {
878
880
  if (!isRequestTimeoutAbort(input.error)) {
879
881
  recordAppRuntimeRetryFailure({
@@ -936,9 +938,18 @@ async function retryAppRuntimeBodyTimeoutOrThrow(input: {
936
938
  action: input.action,
937
939
  attempts: input.attempt,
938
940
  cause: input.error,
941
+ boundaryLabel: input.boundaryLabel,
939
942
  });
940
943
  }
941
944
 
945
+ function runtimeApiBoundaryLabel(
946
+ context: Pick<WorkerRuntimeApiContext, 'boundary'>,
947
+ ): string {
948
+ return context.boundary === 'receipt_gateway'
949
+ ? 'Runtime receipt gateway'
950
+ : 'App runtime API';
951
+ }
952
+
942
953
  export class AppRuntimeApiTransportError extends Error {
943
954
  readonly action: RuntimeApiRequest['action'];
944
955
  readonly attempts: number;
@@ -947,11 +958,12 @@ export class AppRuntimeApiTransportError extends Error {
947
958
  action: RuntimeApiRequest['action'];
948
959
  attempts: number;
949
960
  cause: unknown;
961
+ boundaryLabel?: string;
950
962
  }) {
951
963
  const causeMessage =
952
964
  input.cause instanceof Error ? input.cause.message : String(input.cause);
953
965
  super(
954
- `App runtime API transport exhausted action=${input.action} attempts=${input.attempts}: ${causeMessage}`,
966
+ `${input.boundaryLabel ?? 'App runtime API'} transport exhausted action=${input.action} attempts=${input.attempts}: ${causeMessage}`,
955
967
  { cause: input.cause },
956
968
  );
957
969
  this.name = 'AppRuntimeApiTransportError';
@@ -979,9 +991,10 @@ export class AppRuntimeApiResponseError extends Error {
979
991
  requestId?: string | null;
980
992
  retryable: boolean;
981
993
  detail: string;
994
+ boundaryLabel?: string;
982
995
  }) {
983
996
  super(
984
- `App runtime API ${input.action} failed with status ${input.status}` +
997
+ `${input.boundaryLabel ?? 'App runtime API'} ${input.action} failed with status ${input.status}` +
985
998
  `${input.code ? ` code=${input.code}` : ''}` +
986
999
  `${input.requestId ? ` request_id=${input.requestId}` : ''}: ` +
987
1000
  input.detail,
@@ -1012,6 +1025,7 @@ async function postAppRuntimeApi<TResponse>(
1012
1025
  throw new Error('Worker runtime API requires executorToken.');
1013
1026
  }
1014
1027
  const runtimeFetch = context.fetch ?? fetch;
1028
+ const boundaryLabel = runtimeApiBoundaryLabel(context);
1015
1029
  const vercelHeaders = await vercelProtectionBypassHeaders({
1016
1030
  baseUrl,
1017
1031
  token: context.vercelProtectionBypassToken,
@@ -1091,6 +1105,7 @@ async function postAppRuntimeApi<TResponse>(
1091
1105
  action: body.action,
1092
1106
  attempts: attempt,
1093
1107
  cause: error,
1108
+ boundaryLabel,
1094
1109
  });
1095
1110
  }
1096
1111
  if (response.ok) {
@@ -1114,6 +1129,7 @@ async function postAppRuntimeApi<TResponse>(
1114
1129
  telemetry: retryTelemetry,
1115
1130
  attemptStartedAt,
1116
1131
  httpStatus: response.status,
1132
+ boundaryLabel,
1117
1133
  });
1118
1134
  continue;
1119
1135
  }
@@ -1143,7 +1159,7 @@ async function postAppRuntimeApi<TResponse>(
1143
1159
  finalAttemptStartedAt: attemptStartedAt,
1144
1160
  });
1145
1161
  throw new Error(
1146
- `App runtime API ${body.action} failed with status ${response.status}: response body timed out`,
1162
+ `${boundaryLabel} ${body.action} failed with status ${response.status}: response body timed out`,
1147
1163
  { cause: error },
1148
1164
  );
1149
1165
  }
@@ -1156,6 +1172,7 @@ async function postAppRuntimeApi<TResponse>(
1156
1172
  attemptStartedAt,
1157
1173
  httpStatus: response.status,
1158
1174
  retryAfterMs: appRuntimeRetryAfterMs(response, ''),
1175
+ boundaryLabel,
1159
1176
  });
1160
1177
  continue;
1161
1178
  }
@@ -1221,10 +1238,11 @@ async function postAppRuntimeApi<TResponse>(
1221
1238
  body: responseText,
1222
1239
  }),
1223
1240
  detail: summarizeAppRuntimeErrorBody(responseText),
1241
+ boundaryLabel,
1224
1242
  });
1225
1243
  }
1226
1244
 
1227
- throw new Error(`App runtime API ${body.action} failed after retries.`);
1245
+ throw new Error(`${boundaryLabel} ${body.action} failed after retries.`);
1228
1246
  }
1229
1247
 
1230
1248
  type SignedR2ReadUrlResponse = {
@@ -54,7 +54,7 @@ const DAYTONA_UPLOAD_ATTEMPT_DEADLINE_MS = 90_000;
54
54
  const RUNTIME_POSTGRES_CONNECT_RETRY_PATTERN =
55
55
  /\bRuntime Postgres\b.*\b(connection timed out|connect timeout|ETIMEDOUT|ECONNRESET|ECONNREFUSED|Connection terminated|Connection ended unexpectedly)\b/i;
56
56
  const RUNTIME_RECEIPT_GATEWAY_TRANSPORT_RETRY_PATTERN =
57
- /AppRuntimeApiTransportError: App runtime API transport exhausted action=(?:get|claim|mark|complete|fail|heartbeat|release|skip)_runtime_step_receipts?/i;
57
+ /AppRuntimeApiTransportError: (?:App runtime API|Runtime receipt gateway) transport exhausted action=(?:get|claim|mark|complete|fail|heartbeat|release|skip)_runtime_step_receipts?/i;
58
58
  const RUNTIME_API_TRANSPORT_RETRY_PATTERN =
59
59
  /\bRuntime API request to .+ failed before receiving a response:\s*(?:fetch failed|connection (?:terminated|timed out|closed|reset)|ECONNRESET|ETIMEDOUT|ECONNREFUSED)\b/i;
60
60
  const DAYTONA_INFRASTRUCTURE_RETRY_PATTERN =
@@ -78,6 +78,7 @@ import {
78
78
  sameOwnerTerminalAttemptEpochSql,
79
79
  } from './sheet-attempt-sql';
80
80
  import type { MapRowOutcome } from './durability-store';
81
+ import { RUNTIME_CAPACITY_POLICY } from './runtime-capacity-policy';
81
82
  import {
82
83
  normalizeRuntimeMapInputIndex,
83
84
  prepareRuntimeSheetRowsForJsonTransport,
@@ -349,7 +350,8 @@ const RUNTIME_POSTGRES_RECEIPT_ADMISSION_MAX_QUEUED = 2_000;
349
350
  // memory independently from lightweight receipt requests; overflow is a
350
351
  // retryable 503 and waits outside this long-lived gateway process.
351
352
  const RUNTIME_POSTGRES_SHEET_ADMISSION_MAX_QUEUED = 4;
352
- const RUNTIME_POSTGRES_RECEIPT_ADMISSION_TIMEOUT_MS = 10_000;
353
+ const RUNTIME_POSTGRES_RECEIPT_ADMISSION_TIMEOUT_MS =
354
+ RUNTIME_CAPACITY_POLICY.receiptGateway.admissionTimeoutMs;
353
355
  const RECEIPT_STATUS_QUEUED = RECEIPT_STATUS_CODE.queued;
354
356
  const RECEIPT_STATUS_PENDING = RECEIPT_STATUS_CODE.pending;
355
357
  const RECEIPT_STATUS_RUNNING = RECEIPT_STATUS_CODE.running;
@@ -0,0 +1,59 @@
1
+ /**
2
+ * One fixed capacity policy for the Absurd runtime.
3
+ *
4
+ * Postgres owns backlog. Workers drain it at a predictable rate; queue depth
5
+ * never creates more runtime or receipt traffic by itself. Keep these values
6
+ * together so the worker, queue policy, scaler, gateway, and tests cannot
7
+ * independently invent concurrency or timeout budgets.
8
+ */
9
+ export const RUNTIME_CAPACITY_POLICY = {
10
+ absurd: {
11
+ activeLaneMachines: 2,
12
+ workerSlotsPerMachine: 8,
13
+ perOrgConcurrency: 4,
14
+ },
15
+ receiptGateway: {
16
+ admissionTimeoutMs: 10_000,
17
+ requestTimeoutMs: 30_000,
18
+ },
19
+ } as const;
20
+
21
+ export const ABSURD_GLOBAL_RUN_CONCURRENCY =
22
+ RUNTIME_CAPACITY_POLICY.absurd.activeLaneMachines *
23
+ RUNTIME_CAPACITY_POLICY.absurd.workerSlotsPerMachine;
24
+
25
+ /**
26
+ * Active releases retain fixed capacity. Historical releases stay cold until
27
+ * they have immediately runnable or currently claimed work.
28
+ */
29
+ export function desiredAbsurdLaneMachines(input: {
30
+ active: boolean;
31
+ claimableRuns: number;
32
+ runningRuns?: number;
33
+ }): number {
34
+ if (input.active) {
35
+ return RUNTIME_CAPACITY_POLICY.absurd.activeLaneMachines;
36
+ }
37
+ return input.claimableRuns > 0 || (input.runningRuns ?? 0) > 0 ? 1 : 0;
38
+ }
39
+
40
+ export function assertRuntimeCapacityPolicy(): void {
41
+ if (
42
+ RUNTIME_CAPACITY_POLICY.receiptGateway.requestTimeoutMs <=
43
+ RUNTIME_CAPACITY_POLICY.receiptGateway.admissionTimeoutMs
44
+ ) {
45
+ throw new Error(
46
+ 'Receipt gateway request timeout must exceed its admission timeout.',
47
+ );
48
+ }
49
+ if (
50
+ RUNTIME_CAPACITY_POLICY.absurd.perOrgConcurrency >
51
+ ABSURD_GLOBAL_RUN_CONCURRENCY
52
+ ) {
53
+ throw new Error(
54
+ 'Per-org runtime concurrency cannot exceed global runtime concurrency.',
55
+ );
56
+ }
57
+ }
58
+
59
+ assertRuntimeCapacityPolicy();
package/dist/cli/index.js CHANGED
@@ -718,7 +718,7 @@ var SDK_RELEASE = {
718
718
  // 0.1.253 makes play-page browser opening opt-in and retires --no-open.
719
719
  // 0.1.254 removes the internal operations tree from the published SDK CLI.
720
720
  // Operators use the checkout-local deepline-admin binary instead.
721
- version: "0.1.290",
721
+ version: "0.1.291",
722
722
  contracts: {
723
723
  api: {
724
724
  name: "sdk-http-api",
@@ -703,7 +703,7 @@ var SDK_RELEASE = {
703
703
  // 0.1.253 makes play-page browser opening opt-in and retires --no-open.
704
704
  // 0.1.254 removes the internal operations tree from the published SDK CLI.
705
705
  // Operators use the checkout-local deepline-admin binary instead.
706
- version: "0.1.290",
706
+ version: "0.1.291",
707
707
  contracts: {
708
708
  api: {
709
709
  name: "sdk-http-api",
package/dist/index.js CHANGED
@@ -438,7 +438,7 @@ var SDK_RELEASE = {
438
438
  // 0.1.253 makes play-page browser opening opt-in and retires --no-open.
439
439
  // 0.1.254 removes the internal operations tree from the published SDK CLI.
440
440
  // Operators use the checkout-local deepline-admin binary instead.
441
- version: "0.1.290",
441
+ version: "0.1.291",
442
442
  contracts: {
443
443
  api: {
444
444
  name: "sdk-http-api",
package/dist/index.mjs CHANGED
@@ -367,7 +367,7 @@ var SDK_RELEASE = {
367
367
  // 0.1.253 makes play-page browser opening opt-in and retires --no-open.
368
368
  // 0.1.254 removes the internal operations tree from the published SDK CLI.
369
369
  // Operators use the checkout-local deepline-admin binary instead.
370
- version: "0.1.290",
370
+ version: "0.1.291",
371
371
  contracts: {
372
372
  api: {
373
373
  name: "sdk-http-api",
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "deepline",
3
- "version": "0.1.290",
3
+ "version": "0.1.291",
4
4
  "description": "Deepline SDK + CLI — B2B data enrichment powered by durable cloud execution",
5
5
  "license": "MIT",
6
6
  "repository": {