deepline 0.1.175 → 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.
@@ -90,6 +90,7 @@ const COMPILE_MANIFEST_RETRY_DELAYS_MS = [250, 1_000];
90
90
  const REGISTER_PLAY_ARTIFACTS_COMPILE_CONCURRENCY = 3;
91
91
  const REGISTER_PLAY_ARTIFACTS_MAX_BATCH_COUNT = 3;
92
92
  const REGISTER_PLAY_ARTIFACTS_MAX_BATCH_BYTES = 2_500_000;
93
+ const DEEPLINEAGENT_EXECUTE_TIMEOUT_MS = 15 * 60 * 1000;
93
94
 
94
95
  function normalizePlayRunIntegrationMode(
95
96
  value: unknown,
@@ -202,8 +203,21 @@ function chunkRegisterPlayArtifacts<T>(artifacts: T[]): T[][] {
202
203
  type ExecuteToolRawOptions = {
203
204
  includeToolMetadata?: boolean;
204
205
  responseIntent?: 'raw' | 'row_artifact';
206
+ timeout?: number;
207
+ maxRetries?: number;
205
208
  };
206
209
 
210
+ function resolveToolExecuteTimeoutMs(toolId: string): number | undefined {
211
+ const normalized = toolId.trim().toLowerCase();
212
+ return normalized === 'deeplineagent' ||
213
+ normalized === 'deeplineagent_deeplineagent' ||
214
+ normalized === 'ai_inference' ||
215
+ normalized === 'deeplineagent_ai_inference' ||
216
+ normalized === 'aiinference'
217
+ ? DEEPLINEAGENT_EXECUTE_TIMEOUT_MS
218
+ : undefined;
219
+ }
220
+
207
221
  /**
208
222
  * Standard provider/tool execution envelope returned by low-level SDK calls.
209
223
  *
@@ -1212,7 +1226,12 @@ export class DeeplineClient {
1212
1226
  `/api/v2/integrations/${encodeURIComponent(toolId)}/execute`,
1213
1227
  { payload: input },
1214
1228
  headers,
1215
- { forbiddenAsApiError: true },
1229
+ {
1230
+ forbiddenAsApiError: true,
1231
+ timeout: options?.timeout ?? resolveToolExecuteTimeoutMs(toolId),
1232
+ maxRetries: options?.maxRetries ?? 0,
1233
+ exactUrlOnly: true,
1234
+ },
1216
1235
  );
1217
1236
  }
1218
1237
 
@@ -59,6 +59,10 @@ interface RequestOptions {
59
59
  * most mutating API calls must fail loudly after the first server response.
60
60
  */
61
61
  retryApiErrors?: boolean;
62
+ /** Per-request retry override. Use 0 for possibly delivered mutating calls. */
63
+ maxRetries?: number;
64
+ /** Disable localhost/127.0.0.1 failover for non-idempotent requests. */
65
+ exactUrlOnly?: boolean;
62
66
  }
63
67
 
64
68
  interface StreamOptions {
@@ -222,10 +226,14 @@ export class HttpClient {
222
226
  }
223
227
 
224
228
  let lastError: Error | null = null;
225
- const candidateUrls = buildCandidateUrls(url);
229
+ const candidateUrls = options?.exactUrlOnly
230
+ ? [url]
231
+ : buildCandidateUrls(url);
226
232
  let retryAfterDelayMs: number | null = null;
227
233
 
228
- for (let attempt = 0; attempt <= this.config.maxRetries; attempt++) {
234
+ const maxRetries = options?.maxRetries ?? this.config.maxRetries;
235
+
236
+ for (let attempt = 0; attempt <= maxRetries; attempt++) {
229
237
  if (attempt > 0) {
230
238
  const backoffMs = Math.min(1000 * Math.pow(2, attempt - 1), 30_000);
231
239
  const delayMs =
@@ -270,7 +278,7 @@ export class HttpClient {
270
278
  if (response.status === 429) {
271
279
  const retryAfter = parseRetryAfter(response);
272
280
  lastError = new RateLimitError(retryAfter);
273
- if (attempt < this.config.maxRetries) {
281
+ if (attempt < maxRetries) {
274
282
  retryAfterDelayMs = retryAfter;
275
283
  break;
276
284
  }
@@ -311,7 +319,7 @@ export class HttpClient {
311
319
  : {}),
312
320
  },
313
321
  );
314
- if (retryableApiError && attempt < this.config.maxRetries) {
322
+ if (retryableApiError && attempt < maxRetries) {
315
323
  retryAfterDelayMs = parseOptionalRetryAfter(response);
316
324
  break;
317
325
  }
@@ -350,7 +358,7 @@ export class HttpClient {
350
358
  lastError = new DeeplineError(msg, response.status, apiErrorCode, {
351
359
  response: parsed,
352
360
  });
353
- if (retryableApiError && attempt < this.config.maxRetries) {
361
+ if (retryableApiError && attempt < maxRetries) {
354
362
  retryAfterDelayMs = parseOptionalRetryAfter(response);
355
363
  break;
356
364
  }
@@ -371,7 +379,7 @@ export class HttpClient {
371
379
  }
372
380
  }
373
381
 
374
- if (attempt < this.config.maxRetries) continue;
382
+ if (attempt < maxRetries) continue;
375
383
  }
376
384
 
377
385
  if (lastError instanceof DeeplineError) {
@@ -487,7 +495,11 @@ export class HttpClient {
487
495
  headers?: Record<string, string>,
488
496
  options?: Pick<
489
497
  RequestOptions,
490
- 'forbiddenAsApiError' | 'retryApiErrors' | 'timeout'
498
+ | 'forbiddenAsApiError'
499
+ | 'retryApiErrors'
500
+ | 'timeout'
501
+ | 'maxRetries'
502
+ | 'exactUrlOnly'
491
503
  >,
492
504
  ): Promise<T> {
493
505
  return this.request<T>(path, {
@@ -104,10 +104,10 @@ export const SDK_RELEASE = {
104
104
  // 0.1.111 ships dataset-native tool list getters and result row datasets.
105
105
  // 0.1.154 removes the short-lived generated enrich StepOptions recompute
106
106
  // fields shipped in 0.1.153.
107
- version: '0.1.175',
107
+ version: '0.1.176',
108
108
  apiContract: '2026-06-dataset-handle-results-hard-cutover',
109
109
  supportPolicy: {
110
- latest: '0.1.175',
110
+ latest: '0.1.176',
111
111
  minimumSupported: '0.1.53',
112
112
  deprecatedBelow: '0.1.53',
113
113
  commandMinimumSupported: [
@@ -190,11 +190,33 @@ const MAP_INCREMENTAL_PERSIST_INTERVAL_MS = 100;
190
190
  const MAP_FRAME_FLUSH_INTERVAL_MS = 250;
191
191
  const TOOL_RETRY_AFTER_FALLBACK_MS = 1_000;
192
192
  const TOOL_RETRY_HEARTBEAT_INTERVAL_MS = 30_000;
193
+ const DEEPLINEAGENT_TOOL_RUNTIME_TIMEOUT_MS = 15 * 60 * 1000;
193
194
  const FETCH_TRANSPORT_MAX_ATTEMPTS = 3;
194
195
  const FETCH_TRANSPORT_RETRY_DELAY_MS = 100;
195
196
  type SafeFetchModule = typeof import('@shared_libs/security/safe-fetch');
196
197
  let safeFetchModule: Promise<SafeFetchModule> | null = null;
197
198
 
199
+ export function resolveToolRuntimeTimeoutMs(
200
+ toolId: string,
201
+ requestedTimeoutMs?: number,
202
+ ): number | undefined {
203
+ if (
204
+ typeof requestedTimeoutMs === 'number' &&
205
+ Number.isFinite(requestedTimeoutMs) &&
206
+ requestedTimeoutMs > 0
207
+ ) {
208
+ return Math.max(1, Math.ceil(requestedTimeoutMs));
209
+ }
210
+ const normalized = toolId.trim().toLowerCase();
211
+ return normalized === 'deeplineagent' ||
212
+ normalized === 'deeplineagent_deeplineagent' ||
213
+ normalized === 'ai_inference' ||
214
+ normalized === 'deeplineagent_ai_inference' ||
215
+ normalized === 'aiinference'
216
+ ? DEEPLINEAGENT_TOOL_RUNTIME_TIMEOUT_MS
217
+ : undefined;
218
+ }
219
+
198
220
  function loadSafeFetch(): Promise<SafeFetchModule> {
199
221
  safeFetchModule ??= import('@shared_libs/security/safe-fetch');
200
222
  return safeFetchModule;
@@ -3475,7 +3497,7 @@ export class PlayContextImpl {
3475
3497
  : `Calling tool: ${toolId}`,
3476
3498
  );
3477
3499
  const execution = await this.callToolExecutionAPI(toolId, input, {
3478
- timeoutMs: options?.timeoutMs,
3500
+ timeoutMs: resolveToolRuntimeTimeoutMs(toolId, options?.timeoutMs),
3479
3501
  });
3480
3502
  const wrapped = await this.wrapToolExecutionResult({
3481
3503
  toolId,
@@ -3553,6 +3575,10 @@ export class PlayContextImpl {
3553
3575
  },
3554
3576
  dataPatch: {},
3555
3577
  });
3578
+ const timeoutMs = resolveToolRuntimeTimeoutMs(
3579
+ toolId,
3580
+ options?.timeoutMs,
3581
+ );
3556
3582
  this.toolCallQueue.push({
3557
3583
  callId,
3558
3584
  cacheKey: toolResultCacheKey,
@@ -3562,9 +3588,7 @@ export class PlayContextImpl {
3562
3588
  fieldName,
3563
3589
  toolId,
3564
3590
  input,
3565
- ...(typeof options?.timeoutMs === 'number'
3566
- ? { timeoutMs: options.timeoutMs }
3567
- : {}),
3591
+ ...(timeoutMs !== undefined ? { timeoutMs } : {}),
3568
3592
  ...(typeof options?.receiptWaitMs === 'number'
3569
3593
  ? { receiptWaitMs: options.receiptWaitMs }
3570
3594
  : {}),
@@ -4916,11 +4940,7 @@ export class PlayContextImpl {
4916
4940
  );
4917
4941
  }
4918
4942
  const url = `${this.#options.baseUrl}/api/v2/integrations/${encodeURIComponent(toolId)}/execute`;
4919
- const timeoutMs =
4920
- typeof options?.timeoutMs === 'number' &&
4921
- Number.isFinite(options.timeoutMs)
4922
- ? Math.max(1, Math.ceil(options.timeoutMs))
4923
- : undefined;
4943
+ const timeoutMs = resolveToolRuntimeTimeoutMs(toolId, options?.timeoutMs);
4924
4944
 
4925
4945
  // The Governor's tool slot is the single seam for tool-call budget + the
4926
4946
  // global tool-concurrency backstop + per-(org, provider) pacing. It blocks