deepline 0.3.165 → 0.3.166

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.
@@ -655,6 +655,8 @@ type ExecuteToolRawOptions = {
655
655
  metadata?: Record<string, unknown>;
656
656
  timeout?: number;
657
657
  maxRetries?: number;
658
+ /** Retry transient HTTP API responses when the caller has confirmed safety. */
659
+ retryApiErrors?: boolean;
658
660
  /** Reuse this stable key to recover or retry an ambiguous execution. */
659
661
  idempotencyKey?: string;
660
662
  /** Generate a key and enable recoverable execution before dispatch. */
@@ -699,7 +701,6 @@ export type ExecutionByKeyResult = {
699
701
  */
700
702
  const APIFY_SYNC_DEFAULT_TIMEOUT_MS = 300_000;
701
703
  const APIFY_SYNC_RESPONSE_GRACE_MS = 90_000;
702
-
703
704
  function resolveToolExecuteTimeoutMs(
704
705
  toolId: string,
705
706
  input: Record<string, unknown>,
@@ -3397,6 +3398,7 @@ export class DeeplineClient {
3397
3398
  {
3398
3399
  timeout: requestTimeoutMs,
3399
3400
  maxRetries: idempotencyKey ? 0 : (options?.maxRetries ?? 0),
3401
+ retryApiErrors: options?.retryApiErrors === true,
3400
3402
  exactUrlOnly: true,
3401
3403
  toolId,
3402
3404
  idempotencyKey,
@@ -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.165',
203
+ version: '0.3.166',
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: {
@@ -366,6 +366,7 @@ export type ToolExecutionMetadata = {
366
366
  provider: string;
367
367
  sourceOperation: string;
368
368
  effectiveOperation: string;
369
+ retrySafeTransientHttp?: true;
369
370
  batch: {
370
371
  batchOperation: string | null;
371
372
  maxBatchSize: number;
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.165",
3054
+ version: "0.3.166",
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
@@ -7561,6 +7561,7 @@ var DeeplineClient = class _DeeplineClient {
7561
7561
  {
7562
7562
  timeout: requestTimeoutMs,
7563
7563
  maxRetries: idempotencyKey ? 0 : options?.maxRetries ?? 0,
7564
+ retryApiErrors: options?.retryApiErrors === true,
7564
7565
  exactUrlOnly: true,
7565
7566
  toolId,
7566
7567
  idempotencyKey
@@ -24153,29 +24154,40 @@ function isAdmittedRunVisibilityDelay(error) {
24153
24154
  async function waitForPlayCompletionByStream(input2) {
24154
24155
  let lastPhase = null;
24155
24156
  let reconnectAttempt = 0;
24156
- let nextDurableProbeAt = Date.now() + PLAY_DURABLE_STATUS_PROBE_INTERVAL_MS;
24157
+ const durableStatusProbeIntervalMs = input2.durableStatusProbeIntervalMs ?? PLAY_DURABLE_STATUS_PROBE_INTERVAL_MS;
24158
+ let nextDurableProbeAt = Date.now() + durableStatusProbeIntervalMs;
24159
+ let durableStatusProbe = null;
24157
24160
  const withDashboardUrl = (status) => input2.dashboardUrl ? { ...status, dashboardUrl: input2.dashboardUrl } : status;
24158
24161
  const remainingWaitMs = () => input2.waitTimeoutMs === null ? null : input2.waitTimeoutMs - (Date.now() - input2.startedAt);
24159
24162
  const fetchTerminalStatus = async () => {
24160
- let refreshed;
24161
- try {
24162
- refreshed = await input2.client.getPlayStatus(input2.workflowId, {
24163
- billing: false
24164
- });
24165
- } catch (error) {
24166
- if (isTransientPlayStreamError(error) || isAdmittedRunVisibilityDelay(error)) {
24167
- return null;
24163
+ if (durableStatusProbe) return durableStatusProbe;
24164
+ const probe = (async () => {
24165
+ let refreshed;
24166
+ try {
24167
+ refreshed = await input2.client.getPlayStatus(input2.workflowId, {
24168
+ billing: false
24169
+ });
24170
+ } catch (error) {
24171
+ if (isTransientPlayStreamError(error) || isAdmittedRunVisibilityDelay(error)) {
24172
+ return null;
24173
+ }
24174
+ throw error;
24168
24175
  }
24169
- throw error;
24176
+ return TERMINAL_PLAY_STATUSES2.has(refreshed.status) ? withDashboardUrl(refreshed) : null;
24177
+ })();
24178
+ durableStatusProbe = probe;
24179
+ try {
24180
+ return await probe;
24181
+ } finally {
24182
+ if (durableStatusProbe === probe) durableStatusProbe = null;
24170
24183
  }
24171
- return TERMINAL_PLAY_STATUSES2.has(refreshed.status) ? withDashboardUrl(refreshed) : null;
24172
24184
  };
24173
- const handleLiveEvent = async (event) => {
24185
+ const handleLiveEvent = async (event, probeDurableStatus) => {
24174
24186
  assertPlayWaitNotTimedOut({ ...input2, lastPhase });
24175
24187
  const now = Date.now();
24176
24188
  if (now >= nextDurableProbeAt) {
24177
- nextDurableProbeAt = now + PLAY_DURABLE_STATUS_PROBE_INTERVAL_MS;
24178
- const durableTerminal = await fetchTerminalStatus();
24189
+ nextDurableProbeAt = now + durableStatusProbeIntervalMs;
24190
+ const durableTerminal = await probeDurableStatus();
24179
24191
  if (durableTerminal) {
24180
24192
  return durableTerminal;
24181
24193
  }
@@ -24235,15 +24247,8 @@ async function waitForPlayCompletionByStream(input2) {
24235
24247
  }
24236
24248
  const status = getStatusFromLiveEvent(event);
24237
24249
  if (status && TERMINAL_PLAY_STATUSES2.has(status)) {
24238
- const refreshedStatus = await input2.client.getPlayStatus(
24239
- input2.workflowId,
24240
- {
24241
- billing: false
24242
- }
24243
- );
24244
- if (TERMINAL_PLAY_STATUSES2.has(refreshedStatus.status)) {
24245
- return withDashboardUrl(refreshedStatus);
24246
- }
24250
+ const refreshedStatus = await probeDurableStatus();
24251
+ if (refreshedStatus) return refreshedStatus;
24247
24252
  }
24248
24253
  return null;
24249
24254
  };
@@ -24251,6 +24256,9 @@ async function waitForPlayCompletionByStream(input2) {
24251
24256
  const controller = new AbortController();
24252
24257
  let timedOut = false;
24253
24258
  let sawEvent = false;
24259
+ let durableTerminal = null;
24260
+ let durableProbeError = null;
24261
+ let durableProbeTimer = null;
24254
24262
  const remaining = remainingWaitMs();
24255
24263
  const timeout = remaining === null ? null : setTimeout(
24256
24264
  () => {
@@ -24259,13 +24267,37 @@ async function waitForPlayCompletionByStream(input2) {
24259
24267
  },
24260
24268
  Math.max(1, remaining)
24261
24269
  );
24270
+ const scheduleDurableStatusProbe = () => {
24271
+ durableProbeTimer = setTimeout(() => {
24272
+ durableProbeTimer = null;
24273
+ if (controller.signal.aborted) return;
24274
+ nextDurableProbeAt = Date.now() + durableStatusProbeIntervalMs;
24275
+ void fetchTerminalStatus().then((status) => {
24276
+ if (controller.signal.aborted) return;
24277
+ if (status) {
24278
+ durableTerminal = status;
24279
+ controller.abort();
24280
+ return;
24281
+ }
24282
+ scheduleDurableStatusProbe();
24283
+ }).catch((error) => {
24284
+ if (controller.signal.aborted) return;
24285
+ durableProbeError = error;
24286
+ controller.abort();
24287
+ });
24288
+ }, durableStatusProbeIntervalMs);
24289
+ };
24262
24290
  try {
24291
+ scheduleDurableStatusProbe();
24263
24292
  for await (const event of input2.client.streamPlayRunEvents(
24264
24293
  input2.workflowId,
24265
24294
  { signal: controller.signal }
24266
24295
  )) {
24267
24296
  sawEvent = true;
24268
- const terminal = await handleLiveEvent(event);
24297
+ if (durableTerminal) {
24298
+ return { kind: "terminal", status: durableTerminal };
24299
+ }
24300
+ const terminal = await handleLiveEvent(event, fetchTerminalStatus);
24269
24301
  if (terminal) {
24270
24302
  return { kind: "terminal", status: terminal };
24271
24303
  }
@@ -24274,6 +24306,12 @@ async function waitForPlayCompletionByStream(input2) {
24274
24306
  if (timedOut) {
24275
24307
  return { kind: "timed_out", sawEvent };
24276
24308
  }
24309
+ if (durableTerminal) {
24310
+ return { kind: "terminal", status: durableTerminal };
24311
+ }
24312
+ if (durableProbeError) {
24313
+ throw durableProbeError;
24314
+ }
24277
24315
  if (!isTransientPlayStreamError(error) && !isAdmittedRunVisibilityDelay(error)) {
24278
24316
  throw error;
24279
24317
  }
@@ -24286,6 +24324,19 @@ async function waitForPlayCompletionByStream(input2) {
24286
24324
  if (timeout) {
24287
24325
  clearTimeout(timeout);
24288
24326
  }
24327
+ if (durableProbeTimer) {
24328
+ clearTimeout(durableProbeTimer);
24329
+ }
24330
+ controller.abort();
24331
+ }
24332
+ if (timedOut) {
24333
+ return { kind: "timed_out", sawEvent };
24334
+ }
24335
+ if (durableTerminal) {
24336
+ return { kind: "terminal", status: durableTerminal };
24337
+ }
24338
+ if (durableProbeError) {
24339
+ throw durableProbeError;
24289
24340
  }
24290
24341
  return {
24291
24342
  kind: "ended",
@@ -50218,6 +50269,7 @@ async function executeTool(args) {
50218
50269
  }
50219
50270
  const rawResponse = await client2.executeTool(parsed.toolId, parsed.params, {
50220
50271
  ...parsed.timeoutMs !== void 0 ? { timeout: parsed.timeoutMs } : {},
50272
+ ...metadata.executionMetadata?.retrySafeTransientHttp === true ? { maxRetries: 2, retryApiErrors: true } : {},
50221
50273
  responseIntent,
50222
50274
  ...idempotencyKey ? { idempotencyKey } : {},
50223
50275
  ...parsed.recoveryTimeoutMs !== void 0 ? { recoveryTimeoutMs: parsed.recoveryTimeoutMs } : {}
@@ -51051,13 +51103,19 @@ function isDowngradeAutoUpdateResponse(response) {
51051
51103
  if (!target) return false;
51052
51104
  return compareSemver(target, current) < 0;
51053
51105
  }
51054
- function relaunchCurrentCommand(plan) {
51106
+ function relaunchCurrentCommand(plan, runtime = {}) {
51055
51107
  return new Promise((resolve22) => {
51056
- const command = plan.kind === "python-sidecar" ? plan.sidecarPath : process.execPath;
51057
- const args = plan.kind === "python-sidecar" ? process.argv.slice(2) : process.argv.slice(1);
51108
+ const command = plan.kind === "python-sidecar" ? plan.sidecarPath : runtime.execPath ?? process.execPath;
51109
+ const argv = runtime.argv ?? process.argv;
51110
+ const args = plan.kind === "python-sidecar" ? argv.slice(2) : argv.slice(1);
51111
+ const platform3 = runtime.platform ?? process.platform;
51058
51112
  const child = (0, import_node_child_process7.spawn)(command, args, {
51059
51113
  stdio: "inherit",
51060
- shell: process.platform === "win32",
51114
+ // The Node executable is a native binary and must be spawned directly;
51115
+ // passing `C:\Program Files\...\node.exe` through cmd.exe splits it
51116
+ // at the first space. The Python-sidecar launcher is a `.cmd` file on
51117
+ // Windows and still needs the shell dispatch it has always used.
51118
+ shell: plan.kind === "python-sidecar" && platform3 === "win32",
51061
51119
  env: {
51062
51120
  ...process.env,
51063
51121
  DEEPLINE_NO_AUTO_UPDATE: "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.165",
3049
+ version: "0.3.166",
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
@@ -7556,6 +7556,7 @@ var DeeplineClient = class _DeeplineClient {
7556
7556
  {
7557
7557
  timeout: requestTimeoutMs,
7558
7558
  maxRetries: idempotencyKey ? 0 : options?.maxRetries ?? 0,
7559
+ retryApiErrors: options?.retryApiErrors === true,
7559
7560
  exactUrlOnly: true,
7560
7561
  toolId,
7561
7562
  idempotencyKey
@@ -24225,29 +24226,40 @@ function isAdmittedRunVisibilityDelay(error) {
24225
24226
  async function waitForPlayCompletionByStream(input2) {
24226
24227
  let lastPhase = null;
24227
24228
  let reconnectAttempt = 0;
24228
- let nextDurableProbeAt = Date.now() + PLAY_DURABLE_STATUS_PROBE_INTERVAL_MS;
24229
+ const durableStatusProbeIntervalMs = input2.durableStatusProbeIntervalMs ?? PLAY_DURABLE_STATUS_PROBE_INTERVAL_MS;
24230
+ let nextDurableProbeAt = Date.now() + durableStatusProbeIntervalMs;
24231
+ let durableStatusProbe = null;
24229
24232
  const withDashboardUrl = (status) => input2.dashboardUrl ? { ...status, dashboardUrl: input2.dashboardUrl } : status;
24230
24233
  const remainingWaitMs = () => input2.waitTimeoutMs === null ? null : input2.waitTimeoutMs - (Date.now() - input2.startedAt);
24231
24234
  const fetchTerminalStatus = async () => {
24232
- let refreshed;
24233
- try {
24234
- refreshed = await input2.client.getPlayStatus(input2.workflowId, {
24235
- billing: false
24236
- });
24237
- } catch (error) {
24238
- if (isTransientPlayStreamError(error) || isAdmittedRunVisibilityDelay(error)) {
24239
- return null;
24235
+ if (durableStatusProbe) return durableStatusProbe;
24236
+ const probe = (async () => {
24237
+ let refreshed;
24238
+ try {
24239
+ refreshed = await input2.client.getPlayStatus(input2.workflowId, {
24240
+ billing: false
24241
+ });
24242
+ } catch (error) {
24243
+ if (isTransientPlayStreamError(error) || isAdmittedRunVisibilityDelay(error)) {
24244
+ return null;
24245
+ }
24246
+ throw error;
24240
24247
  }
24241
- throw error;
24248
+ return TERMINAL_PLAY_STATUSES2.has(refreshed.status) ? withDashboardUrl(refreshed) : null;
24249
+ })();
24250
+ durableStatusProbe = probe;
24251
+ try {
24252
+ return await probe;
24253
+ } finally {
24254
+ if (durableStatusProbe === probe) durableStatusProbe = null;
24242
24255
  }
24243
- return TERMINAL_PLAY_STATUSES2.has(refreshed.status) ? withDashboardUrl(refreshed) : null;
24244
24256
  };
24245
- const handleLiveEvent = async (event) => {
24257
+ const handleLiveEvent = async (event, probeDurableStatus) => {
24246
24258
  assertPlayWaitNotTimedOut({ ...input2, lastPhase });
24247
24259
  const now = Date.now();
24248
24260
  if (now >= nextDurableProbeAt) {
24249
- nextDurableProbeAt = now + PLAY_DURABLE_STATUS_PROBE_INTERVAL_MS;
24250
- const durableTerminal = await fetchTerminalStatus();
24261
+ nextDurableProbeAt = now + durableStatusProbeIntervalMs;
24262
+ const durableTerminal = await probeDurableStatus();
24251
24263
  if (durableTerminal) {
24252
24264
  return durableTerminal;
24253
24265
  }
@@ -24307,15 +24319,8 @@ async function waitForPlayCompletionByStream(input2) {
24307
24319
  }
24308
24320
  const status = getStatusFromLiveEvent(event);
24309
24321
  if (status && TERMINAL_PLAY_STATUSES2.has(status)) {
24310
- const refreshedStatus = await input2.client.getPlayStatus(
24311
- input2.workflowId,
24312
- {
24313
- billing: false
24314
- }
24315
- );
24316
- if (TERMINAL_PLAY_STATUSES2.has(refreshedStatus.status)) {
24317
- return withDashboardUrl(refreshedStatus);
24318
- }
24322
+ const refreshedStatus = await probeDurableStatus();
24323
+ if (refreshedStatus) return refreshedStatus;
24319
24324
  }
24320
24325
  return null;
24321
24326
  };
@@ -24323,6 +24328,9 @@ async function waitForPlayCompletionByStream(input2) {
24323
24328
  const controller = new AbortController();
24324
24329
  let timedOut = false;
24325
24330
  let sawEvent = false;
24331
+ let durableTerminal = null;
24332
+ let durableProbeError = null;
24333
+ let durableProbeTimer = null;
24326
24334
  const remaining = remainingWaitMs();
24327
24335
  const timeout = remaining === null ? null : setTimeout(
24328
24336
  () => {
@@ -24331,13 +24339,37 @@ async function waitForPlayCompletionByStream(input2) {
24331
24339
  },
24332
24340
  Math.max(1, remaining)
24333
24341
  );
24342
+ const scheduleDurableStatusProbe = () => {
24343
+ durableProbeTimer = setTimeout(() => {
24344
+ durableProbeTimer = null;
24345
+ if (controller.signal.aborted) return;
24346
+ nextDurableProbeAt = Date.now() + durableStatusProbeIntervalMs;
24347
+ void fetchTerminalStatus().then((status) => {
24348
+ if (controller.signal.aborted) return;
24349
+ if (status) {
24350
+ durableTerminal = status;
24351
+ controller.abort();
24352
+ return;
24353
+ }
24354
+ scheduleDurableStatusProbe();
24355
+ }).catch((error) => {
24356
+ if (controller.signal.aborted) return;
24357
+ durableProbeError = error;
24358
+ controller.abort();
24359
+ });
24360
+ }, durableStatusProbeIntervalMs);
24361
+ };
24334
24362
  try {
24363
+ scheduleDurableStatusProbe();
24335
24364
  for await (const event of input2.client.streamPlayRunEvents(
24336
24365
  input2.workflowId,
24337
24366
  { signal: controller.signal }
24338
24367
  )) {
24339
24368
  sawEvent = true;
24340
- const terminal = await handleLiveEvent(event);
24369
+ if (durableTerminal) {
24370
+ return { kind: "terminal", status: durableTerminal };
24371
+ }
24372
+ const terminal = await handleLiveEvent(event, fetchTerminalStatus);
24341
24373
  if (terminal) {
24342
24374
  return { kind: "terminal", status: terminal };
24343
24375
  }
@@ -24346,6 +24378,12 @@ async function waitForPlayCompletionByStream(input2) {
24346
24378
  if (timedOut) {
24347
24379
  return { kind: "timed_out", sawEvent };
24348
24380
  }
24381
+ if (durableTerminal) {
24382
+ return { kind: "terminal", status: durableTerminal };
24383
+ }
24384
+ if (durableProbeError) {
24385
+ throw durableProbeError;
24386
+ }
24349
24387
  if (!isTransientPlayStreamError(error) && !isAdmittedRunVisibilityDelay(error)) {
24350
24388
  throw error;
24351
24389
  }
@@ -24358,6 +24396,19 @@ async function waitForPlayCompletionByStream(input2) {
24358
24396
  if (timeout) {
24359
24397
  clearTimeout(timeout);
24360
24398
  }
24399
+ if (durableProbeTimer) {
24400
+ clearTimeout(durableProbeTimer);
24401
+ }
24402
+ controller.abort();
24403
+ }
24404
+ if (timedOut) {
24405
+ return { kind: "timed_out", sawEvent };
24406
+ }
24407
+ if (durableTerminal) {
24408
+ return { kind: "terminal", status: durableTerminal };
24409
+ }
24410
+ if (durableProbeError) {
24411
+ throw durableProbeError;
24361
24412
  }
24362
24413
  return {
24363
24414
  kind: "ended",
@@ -50363,6 +50414,7 @@ async function executeTool(args) {
50363
50414
  }
50364
50415
  const rawResponse = await client2.executeTool(parsed.toolId, parsed.params, {
50365
50416
  ...parsed.timeoutMs !== void 0 ? { timeout: parsed.timeoutMs } : {},
50417
+ ...metadata.executionMetadata?.retrySafeTransientHttp === true ? { maxRetries: 2, retryApiErrors: true } : {},
50366
50418
  responseIntent,
50367
50419
  ...idempotencyKey ? { idempotencyKey } : {},
50368
50420
  ...parsed.recoveryTimeoutMs !== void 0 ? { recoveryTimeoutMs: parsed.recoveryTimeoutMs } : {}
@@ -51196,13 +51248,19 @@ function isDowngradeAutoUpdateResponse(response) {
51196
51248
  if (!target) return false;
51197
51249
  return compareSemver(target, current) < 0;
51198
51250
  }
51199
- function relaunchCurrentCommand(plan) {
51251
+ function relaunchCurrentCommand(plan, runtime = {}) {
51200
51252
  return new Promise((resolve22) => {
51201
- const command = plan.kind === "python-sidecar" ? plan.sidecarPath : process.execPath;
51202
- const args = plan.kind === "python-sidecar" ? process.argv.slice(2) : process.argv.slice(1);
51253
+ const command = plan.kind === "python-sidecar" ? plan.sidecarPath : runtime.execPath ?? process.execPath;
51254
+ const argv = runtime.argv ?? process.argv;
51255
+ const args = plan.kind === "python-sidecar" ? argv.slice(2) : argv.slice(1);
51256
+ const platform3 = runtime.platform ?? process.platform;
51203
51257
  const child = spawn5(command, args, {
51204
51258
  stdio: "inherit",
51205
- shell: process.platform === "win32",
51259
+ // The Node executable is a native binary and must be spawned directly;
51260
+ // passing `C:\Program Files\...\node.exe` through cmd.exe splits it
51261
+ // at the first space. The Python-sidecar launcher is a `.cmd` file on
51262
+ // Windows and still needs the shell dispatch it has always used.
51263
+ shell: plan.kind === "python-sidecar" && platform3 === "win32",
51206
51264
  env: {
51207
51265
  ...process.env,
51208
51266
  DEEPLINE_NO_AUTO_UPDATE: "1"
package/dist/index.d.mts CHANGED
@@ -1280,6 +1280,7 @@ type ToolExecutionMetadata = {
1280
1280
  provider: string;
1281
1281
  sourceOperation: string;
1282
1282
  effectiveOperation: string;
1283
+ retrySafeTransientHttp?: true;
1283
1284
  batch: {
1284
1285
  batchOperation: string | null;
1285
1286
  maxBatchSize: number;
@@ -3095,6 +3096,8 @@ type ExecuteToolRawOptions = {
3095
3096
  metadata?: Record<string, unknown>;
3096
3097
  timeout?: number;
3097
3098
  maxRetries?: number;
3099
+ /** Retry transient HTTP API responses when the caller has confirmed safety. */
3100
+ retryApiErrors?: boolean;
3098
3101
  /** Reuse this stable key to recover or retry an ambiguous execution. */
3099
3102
  idempotencyKey?: string;
3100
3103
  /** Generate a key and enable recoverable execution before dispatch. */
package/dist/index.d.ts CHANGED
@@ -1280,6 +1280,7 @@ type ToolExecutionMetadata = {
1280
1280
  provider: string;
1281
1281
  sourceOperation: string;
1282
1282
  effectiveOperation: string;
1283
+ retrySafeTransientHttp?: true;
1283
1284
  batch: {
1284
1285
  batchOperation: string | null;
1285
1286
  maxBatchSize: number;
@@ -3095,6 +3096,8 @@ type ExecuteToolRawOptions = {
3095
3096
  metadata?: Record<string, unknown>;
3096
3097
  timeout?: number;
3097
3098
  maxRetries?: number;
3099
+ /** Retry transient HTTP API responses when the caller has confirmed safety. */
3100
+ retryApiErrors?: boolean;
3098
3101
  /** Reuse this stable key to recover or retry an ambiguous execution. */
3099
3102
  idempotencyKey?: string;
3100
3103
  /** Generate a key and enable recoverable execution before dispatch. */
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.165",
867
+ version: "0.3.166",
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
@@ -5252,6 +5252,7 @@ var DeeplineClient = class _DeeplineClient {
5252
5252
  {
5253
5253
  timeout: requestTimeoutMs,
5254
5254
  maxRetries: idempotencyKey ? 0 : options?.maxRetries ?? 0,
5255
+ retryApiErrors: options?.retryApiErrors === true,
5255
5256
  exactUrlOnly: true,
5256
5257
  toolId,
5257
5258
  idempotencyKey
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.165",
771
+ version: "0.3.166",
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
@@ -5156,6 +5156,7 @@ var DeeplineClient = class _DeeplineClient {
5156
5156
  {
5157
5157
  timeout: requestTimeoutMs,
5158
5158
  maxRetries: idempotencyKey ? 0 : options?.maxRetries ?? 0,
5159
+ retryApiErrors: options?.retryApiErrors === true,
5159
5160
  exactUrlOnly: true,
5160
5161
  toolId,
5161
5162
  idempotencyKey
@@ -149,7 +149,7 @@ type SdkRelease = {
149
149
  supportPolicy: SdkSupportPolicy;
150
150
  };
151
151
  declare const SDK_RELEASE: {
152
- readonly version: "0.3.165";
152
+ readonly version: "0.3.166";
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.165";
152
+ readonly version: "0.3.166";
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.165",
77
+ version: "0.3.166",
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.165",
51
+ version: "0.3.166",
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.165",
3
+ "version": "0.3.166",
4
4
  "description": "GTM data CLI and TypeScript SDK for coding agents",
5
5
  "license": "MIT",
6
6
  "homepage": "https://code.deepline.com",