deepline 0.1.227 → 0.1.228

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.
@@ -522,6 +522,14 @@ function resolveRuntimeApiHeaders(
522
522
  'content-type': 'application/json',
523
523
  authorization: `Bearer ${token}`,
524
524
  [PLAY_RUNTIME_CONTRACT_HEADER]: String(PLAY_RUNTIME_CONTRACT),
525
+ // A run has many callback HTTP attempts. Preserve the logical run
526
+ // correlation in headers while Vercel keeps its own per-attempt request id.
527
+ ...(context.runId?.trim()
528
+ ? {
529
+ 'x-deepline-run-id': context.runId.trim(),
530
+ 'x-deepline-correlation-id': `run:${context.runId.trim()}`,
531
+ }
532
+ : {}),
525
533
  ...vercelHeaders,
526
534
  ...(context.runtimeTestFaultHeader?.trim()
527
535
  ? {
@@ -677,7 +685,7 @@ function runtimeApiMaxAttempts(
677
685
  }
678
686
 
679
687
  export function isTransientRuntimeApiErrorMessage(message: string): boolean {
680
- return /timeout exceeded when trying to connect|timed out|fetch failed|ECONNRESET|ECONNREFUSED|UND_ERR_CONNECT_TIMEOUT|requested endpoint could not be found, or you don't have access|RUNTIME_SCHEDULER_SATURATED|Runtime scheduler DB pool is saturated|Runtime scheduler DB circuit breaker is open/i.test(
688
+ return /timeout exceeded when trying to connect|timed out|fetch failed|ECONNRESET|ECONNREFUSED|UND_ERR_CONNECT_TIMEOUT|requested endpoint could not be found, or you don't have access|RUNTIME_SCHEDULER_(?:SATURATED|UNAVAILABLE)|Runtime scheduler DB pool is saturated|Runtime scheduler DB circuit breaker is open/i.test(
681
689
  message,
682
690
  );
683
691
  }
@@ -1779,11 +1787,22 @@ function isMissingRelationError(error: unknown): boolean {
1779
1787
  }
1780
1788
 
1781
1789
  function isPostgresPermissionDeniedError(error: unknown): boolean {
1782
- return (
1783
- error !== null &&
1784
- typeof error === 'object' &&
1785
- 'code' in error &&
1786
- String(error.code) === '42501'
1790
+ if (error === null || typeof error !== 'object') {
1791
+ return false;
1792
+ }
1793
+ if ('code' in error && String(error.code) === '42501') {
1794
+ return true;
1795
+ }
1796
+ const message =
1797
+ 'message' in error && typeof error.message === 'string'
1798
+ ? error.message
1799
+ : '';
1800
+ // Postgres errors raised by a direct session retain SQLSTATE 42501. The
1801
+ // same failure crossing the runtime API boundary is intentionally rendered
1802
+ // as a safe Error message, so preserve the exact permission-denied shape as
1803
+ // the repair signal without treating arbitrary 500s as storage drift.
1804
+ return /permission denied for (?:database|schema|relation|table|sequence)/i.test(
1805
+ message,
1787
1806
  );
1788
1807
  }
1789
1808
 
@@ -2951,12 +2970,28 @@ export async function ensureRuntimeSheet(
2951
2970
  sheetContract: PlaySheetContract;
2952
2971
  },
2953
2972
  ): Promise<void> {
2954
- await postRuntimeApi<{ ok: true }>(context, {
2955
- action: 'ensure_sheet',
2973
+ const request = {
2974
+ action: 'ensure_sheet' as const,
2956
2975
  ...input,
2957
2976
  runId: context.runId ?? null,
2958
2977
  userEmail: normalizeRuntimeUserEmail(context.userEmail),
2959
- });
2978
+ };
2979
+ try {
2980
+ await postRuntimeApi<{ ok: true }>(context, request);
2981
+ } catch (error) {
2982
+ if (!isPostgresPermissionDeniedError(error)) {
2983
+ throw error;
2984
+ }
2985
+ // Fresh tenant databases can become visible through the pooled endpoint
2986
+ // before their runtime-role grants are usable. Non-preloaded file runs hit
2987
+ // ensure_sheet before any direct Postgres operation, so the existing
2988
+ // operation-level self-heal cannot observe this boundary. Repair the
2989
+ // canonical storage contract once, then retry the exact ensure request.
2990
+ await repairRuntimeStorageGrants(context, {
2991
+ playName: input.playName,
2992
+ });
2993
+ await postRuntimeApi<{ ok: true }>(context, request);
2994
+ }
2960
2995
  }
2961
2996
 
2962
2997
  async function prepareRuntimeSheetDatasetRows(
@@ -0,0 +1,63 @@
1
+ import { redactLedgerString } from './ledger-safe-payload';
2
+
3
+ type ErrorLike = Record<string, unknown>;
4
+
5
+ export type TransportErrorDiagnostic = {
6
+ name: string | null;
7
+ message: string | null;
8
+ code: string | null;
9
+ errno: string | null;
10
+ syscall: string | null;
11
+ cause: TransportErrorDiagnostic | null;
12
+ };
13
+
14
+ function asErrorLike(value: unknown): ErrorLike | null {
15
+ return value !== null && typeof value === 'object'
16
+ ? (value as ErrorLike)
17
+ : null;
18
+ }
19
+
20
+ function safeString(value: unknown): string | null {
21
+ if (typeof value !== 'string' && typeof value !== 'number') return null;
22
+ return redactLedgerString(String(value))?.slice(0, 500) ?? null;
23
+ }
24
+
25
+ export function transportGatewayOriginForDiagnostic(url: string): string {
26
+ try {
27
+ return new URL(url).origin;
28
+ } catch {
29
+ return '<invalid-gateway-origin>';
30
+ }
31
+ }
32
+
33
+ /**
34
+ * Make a small, secret-redacted transport diagnostic that can safely cross the
35
+ * runner -> gateway -> durable run-log boundary. Keep stacks in process logs:
36
+ * serializing them into run state leaks implementation details and is rarely
37
+ * useful without the original error's code/errno/cause chain.
38
+ */
39
+ export function describeTransportError(
40
+ error: unknown,
41
+ depth = 0,
42
+ ): TransportErrorDiagnostic {
43
+ const value = asErrorLike(error);
44
+ const errorValue = error instanceof Error ? error : null;
45
+ const name =
46
+ safeString(errorValue?.name ?? value?.name) ?? (value ? 'Error' : null);
47
+ const message = safeString(errorValue?.message ?? value?.message ?? error);
48
+ const cause = value?.cause;
49
+
50
+ return {
51
+ name,
52
+ message,
53
+ code: safeString(value?.code),
54
+ errno: safeString(value?.errno),
55
+ syscall: safeString(value?.syscall),
56
+ // A short cause chain is enough for fetch/undici errors and prevents a
57
+ // pathological custom error graph from making durable traces unbounded.
58
+ cause:
59
+ cause !== undefined && depth < 2
60
+ ? describeTransportError(cause, depth + 1)
61
+ : null,
62
+ };
63
+ }
package/dist/cli/index.js CHANGED
@@ -625,10 +625,10 @@ var SDK_RELEASE = {
625
625
  // 0.1.175 ships loud `deepline enrich` empty-waterfall reporting.
626
626
  // 0.1.220 deprecates SDK CLI versions below 0.1.219 and updates them
627
627
  // automatically without blocking their current command.
628
- version: "0.1.227",
628
+ version: "0.1.228",
629
629
  apiContract: "2026-06-dataset-handle-results-hard-cutover",
630
630
  supportPolicy: {
631
- latest: "0.1.227",
631
+ latest: "0.1.228",
632
632
  minimumSupported: "0.1.53",
633
633
  deprecatedBelow: "0.1.219",
634
634
  commandMinimumSupported: [
@@ -1691,8 +1691,9 @@ function normalizePlayRunLifecycleStatus(value) {
1691
1691
  return "running";
1692
1692
  case "running":
1693
1693
  case "started":
1694
- case "waiting":
1695
1694
  return "running";
1695
+ case "waiting":
1696
+ return "waiting";
1696
1697
  case "completed":
1697
1698
  case "complete":
1698
1699
  case "succeeded":
@@ -2466,8 +2467,16 @@ function chunkRegisterPlayArtifacts(artifacts) {
2466
2467
  }
2467
2468
  return chunks;
2468
2469
  }
2469
- function resolveToolExecuteTimeoutMs(toolId) {
2470
+ var APIFY_SYNC_DEFAULT_TIMEOUT_MS = 3e5;
2471
+ var APIFY_SYNC_RESPONSE_GRACE_MS = 9e4;
2472
+ function resolveToolExecuteTimeoutMs(toolId, input2) {
2470
2473
  const normalized = toolId.trim().toLowerCase();
2474
+ if (normalized === "apify_run_actor_sync") {
2475
+ const requestedTimeoutMs = input2.timeoutMs ?? APIFY_SYNC_DEFAULT_TIMEOUT_MS;
2476
+ if (typeof requestedTimeoutMs === "number" && Number.isFinite(requestedTimeoutMs) && requestedTimeoutMs > 0) {
2477
+ return Math.floor(requestedTimeoutMs) + APIFY_SYNC_RESPONSE_GRACE_MS;
2478
+ }
2479
+ }
2471
2480
  return normalized === "deeplineagent" || normalized === "deeplineagent_deeplineagent" || normalized === "ai_inference" || normalized === "deeplineagent_ai_inference" || normalized === "aiinference" ? DEEPLINEAGENT_EXECUTE_TIMEOUT_MS : void 0;
2472
2481
  }
2473
2482
  var RUNS_FAILED_LOG_LIMIT = 20;
@@ -2967,7 +2976,7 @@ var DeeplineClient = class {
2967
2976
  headers,
2968
2977
  {
2969
2978
  forbiddenAsApiError: true,
2970
- timeout: options?.timeout ?? resolveToolExecuteTimeoutMs(toolId),
2979
+ timeout: options?.timeout ?? resolveToolExecuteTimeoutMs(toolId, input2),
2971
2980
  maxRetries: options?.maxRetries ?? 0,
2972
2981
  exactUrlOnly: true
2973
2982
  }
@@ -10436,7 +10445,7 @@ Examples:
10436
10445
  deepline plays bootstrap company-list --from provider:crustdata_companydb_search --limit 5 --out companies.play.ts
10437
10446
 
10438
10447
  deepline plays bootstrap monitor-triggered --out on-new-row.play.ts
10439
- deepline plays bootstrap monitor-triggered --tool tamradar.company_radar --stream company_job_openings --out on-new-job.play.ts
10448
+ deepline plays bootstrap monitor-triggered --tool deepline_native.company_radar --stream company_job_openings --out on-new-job.play.ts
10440
10449
  `
10441
10450
  ).option("--name <name>", "Generated play name").option(
10442
10451
  "--from <ref>",
@@ -12055,6 +12064,15 @@ function getStatusFromLiveEvent(event) {
12055
12064
  const payload = getEventPayload(event);
12056
12065
  return playStatusValue(payload.status) ?? playStatusValue(getRunRecordFromPackage(payload)?.status);
12057
12066
  }
12067
+ function writePlayWaitingHint(input2) {
12068
+ if (getStatusFromLiveEvent(input2.event) !== "waiting") return;
12069
+ const runId = getRunIdFromLiveEvent(input2.event);
12070
+ if (!runId || input2.state.waitingRunId === runId) return;
12071
+ input2.state.waitingRunId = runId;
12072
+ input2.progress.writeLine(
12073
+ `[play waiting] ${runId} is waiting for an external approval or event. The command will continue watching; inspect it with 'deepline runs get ${runId} --full --json'.`
12074
+ );
12075
+ }
12058
12076
  function getFinalStatusFromLiveEvent(event) {
12059
12077
  if (event.type !== "play.run.snapshot" && event.type !== "play.run.status" && event.type !== "play.run.final_status") {
12060
12078
  return null;
@@ -12403,6 +12421,11 @@ async function waitForPlayCompletionByStream(input2) {
12403
12421
  lastPhase = phase;
12404
12422
  input2.progress.phase(phase);
12405
12423
  }
12424
+ writePlayWaitingHint({
12425
+ event,
12426
+ state: input2.state,
12427
+ progress: input2.progress
12428
+ });
12406
12429
  emitLiveDebugTableHints({
12407
12430
  event,
12408
12431
  playName: input2.playName,
@@ -12735,6 +12758,11 @@ async function startAndWaitForPlayCompletionByStreamOnce(input2) {
12735
12758
  lastPhase = phase;
12736
12759
  input2.progress.phase(phase);
12737
12760
  }
12761
+ writePlayWaitingHint({
12762
+ event,
12763
+ state,
12764
+ progress: input2.progress
12765
+ });
12738
12766
  printPlayLogLines({
12739
12767
  lines: getLogLinesFromLiveEvent(event),
12740
12768
  status: null,
@@ -26128,9 +26156,14 @@ async function listTools(args) {
26128
26156
  return 0;
26129
26157
  }
26130
26158
  async function searchTools(queryInput, options = {}) {
26131
- const query = queryInput.trim();
26132
- if (!query) {
26133
- console.error("Usage: deepline tools search <query> [--json]");
26159
+ const query = queryInput?.trim() ?? "";
26160
+ const hasStructuredSearch = Boolean(
26161
+ options.categories?.trim() || options.searchTerms?.trim()
26162
+ );
26163
+ if (!query && !hasStructuredSearch) {
26164
+ console.error(
26165
+ "Usage: deepline tools search [query] --categories <categories> [--search_terms <terms>] [--json]"
26166
+ );
26134
26167
  return 1;
26135
26168
  }
26136
26169
  const client2 = new DeeplineClient();
@@ -26366,7 +26399,7 @@ Examples:
26366
26399
  includeSearchDebug: Boolean(options.includeSearchDebug)
26367
26400
  });
26368
26401
  });
26369
- addToolSearchCommand(tools.command("search <query>"));
26402
+ addToolSearchCommand(tools.command("search [query]"));
26370
26403
  tools.command("grep <query>").description(
26371
26404
  "Literal grep over tool ids, descriptions, categories, and input fields."
26372
26405
  ).addHelpText(
@@ -27026,6 +27059,28 @@ function samplePayload(samples, key) {
27026
27059
  function commandEnvelopeFromRawResponse(rawResponse) {
27027
27060
  return isRecord8(rawResponse) ? { ...rawResponse } : { status: "completed", result: rawResponse };
27028
27061
  }
27062
+ function apifySyncRecoveryNext(rawResponse) {
27063
+ if (!isRecord8(rawResponse) || rawResponse.status !== "running") return null;
27064
+ const toolResponse = recordField2(rawResponse, "toolResponse");
27065
+ const raw = recordField2(toolResponse, "raw");
27066
+ if (raw.state !== "awaiting_apify") return null;
27067
+ const next = recordField2(raw, "next");
27068
+ const getActorRun = recordField2(next, "getActorRun");
27069
+ const getActorRunTool = stringField2(getActorRun, "tool");
27070
+ const getActorRunPayload = recordField2(getActorRun, "payload");
27071
+ if (!getActorRunTool || Object.keys(getActorRunPayload).length === 0) {
27072
+ return null;
27073
+ }
27074
+ const getDatasetItems = recordField2(next, "getDatasetItems");
27075
+ const getDatasetItemsTool = stringField2(getDatasetItems, "tool");
27076
+ const getDatasetItemsPayload = recordField2(getDatasetItems, "payload");
27077
+ return {
27078
+ getActorRun: `deepline tools execute ${getActorRunTool} --input ${shellQuote4(JSON.stringify(getActorRunPayload))} --json`,
27079
+ ...getDatasetItemsTool && Object.keys(getDatasetItemsPayload).length > 0 ? {
27080
+ getDatasetItems: `deepline tools execute ${getDatasetItemsTool} --input ${shellQuote4(JSON.stringify(getDatasetItemsPayload))} --json`
27081
+ } : {}
27082
+ };
27083
+ }
27029
27084
  function listExtractorPathsFromUsageGuidance(tool) {
27030
27085
  const toolExecutionResult = tool.usageGuidance?.toolExecutionResult;
27031
27086
  const extractedLists = Array.isArray(toolExecutionResult?.extractedLists) ? toolExecutionResult.extractedLists : isRecord8(toolExecutionResult?.extractedLists) ? Object.values(toolExecutionResult.extractedLists) : [];
@@ -27271,6 +27326,7 @@ export default definePlay(${JSON.stringify(playName)}, async (ctx) => {
27271
27326
  }
27272
27327
  function buildToolExecuteBaseEnvelope(input2) {
27273
27328
  const envelope = commandEnvelopeFromRawResponse(input2.rawResponse);
27329
+ const apifyRecovery = apifySyncRecoveryNext(input2.rawResponse);
27274
27330
  const summaryEntries = Object.entries(input2.summary);
27275
27331
  const outputPreview = input2.listConversion ? {
27276
27332
  kind: "list",
@@ -27294,6 +27350,14 @@ function buildToolExecuteBaseEnvelope(input2) {
27294
27350
  label: "next",
27295
27351
  command: "move starter script into a project folder and expand it into a Deepline play"
27296
27352
  }
27353
+ ] : apifyRecovery ? [
27354
+ { label: "check Apify run", command: apifyRecovery.getActorRun },
27355
+ ...apifyRecovery.getDatasetItems ? [
27356
+ {
27357
+ label: "get Apify dataset items",
27358
+ command: apifyRecovery.getDatasetItems
27359
+ }
27360
+ ] : []
27297
27361
  ] : [];
27298
27362
  return {
27299
27363
  ...envelope,
@@ -27301,6 +27365,7 @@ function buildToolExecuteBaseEnvelope(input2) {
27301
27365
  ...summaryEntries.length > 0 ? { summary: input2.summary } : {},
27302
27366
  next: {
27303
27367
  inspect: inspectCommand,
27368
+ ...apifyRecovery ?? {},
27304
27369
  playDebugging: "When fixing a play getter, inspect returned dataset handles with runs get and export rows with runs export; do not copy CLI preview paths blindly.",
27305
27370
  ...input2.listConversion ? {
27306
27371
  expandToPlay: "Use stable map and step keys so reruns are idempotent: completed rows are reused, and only missing or stale work runs again.",
@@ -27321,7 +27386,9 @@ function buildToolExecuteBaseEnvelope(input2) {
27321
27386
  ] : [
27322
27387
  {
27323
27388
  title: "result",
27324
- lines: summaryEntries.length > 0 ? summaryEntries.map(
27389
+ lines: apifyRecovery ? [
27390
+ "Apify is still running. Run the follow-up command(s) below."
27391
+ ] : summaryEntries.length > 0 ? summaryEntries.map(
27325
27392
  ([key, value]) => `${key}=${String(value)}`
27326
27393
  ) : [JSON.stringify(input2.rawResponse, null, 2)]
27327
27394
  }
@@ -610,10 +610,10 @@ var SDK_RELEASE = {
610
610
  // 0.1.175 ships loud `deepline enrich` empty-waterfall reporting.
611
611
  // 0.1.220 deprecates SDK CLI versions below 0.1.219 and updates them
612
612
  // automatically without blocking their current command.
613
- version: "0.1.227",
613
+ version: "0.1.228",
614
614
  apiContract: "2026-06-dataset-handle-results-hard-cutover",
615
615
  supportPolicy: {
616
- latest: "0.1.227",
616
+ latest: "0.1.228",
617
617
  minimumSupported: "0.1.53",
618
618
  deprecatedBelow: "0.1.219",
619
619
  commandMinimumSupported: [
@@ -1676,8 +1676,9 @@ function normalizePlayRunLifecycleStatus(value) {
1676
1676
  return "running";
1677
1677
  case "running":
1678
1678
  case "started":
1679
- case "waiting":
1680
1679
  return "running";
1680
+ case "waiting":
1681
+ return "waiting";
1681
1682
  case "completed":
1682
1683
  case "complete":
1683
1684
  case "succeeded":
@@ -2451,8 +2452,16 @@ function chunkRegisterPlayArtifacts(artifacts) {
2451
2452
  }
2452
2453
  return chunks;
2453
2454
  }
2454
- function resolveToolExecuteTimeoutMs(toolId) {
2455
+ var APIFY_SYNC_DEFAULT_TIMEOUT_MS = 3e5;
2456
+ var APIFY_SYNC_RESPONSE_GRACE_MS = 9e4;
2457
+ function resolveToolExecuteTimeoutMs(toolId, input2) {
2455
2458
  const normalized = toolId.trim().toLowerCase();
2459
+ if (normalized === "apify_run_actor_sync") {
2460
+ const requestedTimeoutMs = input2.timeoutMs ?? APIFY_SYNC_DEFAULT_TIMEOUT_MS;
2461
+ if (typeof requestedTimeoutMs === "number" && Number.isFinite(requestedTimeoutMs) && requestedTimeoutMs > 0) {
2462
+ return Math.floor(requestedTimeoutMs) + APIFY_SYNC_RESPONSE_GRACE_MS;
2463
+ }
2464
+ }
2456
2465
  return normalized === "deeplineagent" || normalized === "deeplineagent_deeplineagent" || normalized === "ai_inference" || normalized === "deeplineagent_ai_inference" || normalized === "aiinference" ? DEEPLINEAGENT_EXECUTE_TIMEOUT_MS : void 0;
2457
2466
  }
2458
2467
  var RUNS_FAILED_LOG_LIMIT = 20;
@@ -2952,7 +2961,7 @@ var DeeplineClient = class {
2952
2961
  headers,
2953
2962
  {
2954
2963
  forbiddenAsApiError: true,
2955
- timeout: options?.timeout ?? resolveToolExecuteTimeoutMs(toolId),
2964
+ timeout: options?.timeout ?? resolveToolExecuteTimeoutMs(toolId, input2),
2956
2965
  maxRetries: options?.maxRetries ?? 0,
2957
2966
  exactUrlOnly: true
2958
2967
  }
@@ -10465,7 +10474,7 @@ Examples:
10465
10474
  deepline plays bootstrap company-list --from provider:crustdata_companydb_search --limit 5 --out companies.play.ts
10466
10475
 
10467
10476
  deepline plays bootstrap monitor-triggered --out on-new-row.play.ts
10468
- deepline plays bootstrap monitor-triggered --tool tamradar.company_radar --stream company_job_openings --out on-new-job.play.ts
10477
+ deepline plays bootstrap monitor-triggered --tool deepline_native.company_radar --stream company_job_openings --out on-new-job.play.ts
10469
10478
  `
10470
10479
  ).option("--name <name>", "Generated play name").option(
10471
10480
  "--from <ref>",
@@ -12084,6 +12093,15 @@ function getStatusFromLiveEvent(event) {
12084
12093
  const payload = getEventPayload(event);
12085
12094
  return playStatusValue(payload.status) ?? playStatusValue(getRunRecordFromPackage(payload)?.status);
12086
12095
  }
12096
+ function writePlayWaitingHint(input2) {
12097
+ if (getStatusFromLiveEvent(input2.event) !== "waiting") return;
12098
+ const runId = getRunIdFromLiveEvent(input2.event);
12099
+ if (!runId || input2.state.waitingRunId === runId) return;
12100
+ input2.state.waitingRunId = runId;
12101
+ input2.progress.writeLine(
12102
+ `[play waiting] ${runId} is waiting for an external approval or event. The command will continue watching; inspect it with 'deepline runs get ${runId} --full --json'.`
12103
+ );
12104
+ }
12087
12105
  function getFinalStatusFromLiveEvent(event) {
12088
12106
  if (event.type !== "play.run.snapshot" && event.type !== "play.run.status" && event.type !== "play.run.final_status") {
12089
12107
  return null;
@@ -12432,6 +12450,11 @@ async function waitForPlayCompletionByStream(input2) {
12432
12450
  lastPhase = phase;
12433
12451
  input2.progress.phase(phase);
12434
12452
  }
12453
+ writePlayWaitingHint({
12454
+ event,
12455
+ state: input2.state,
12456
+ progress: input2.progress
12457
+ });
12435
12458
  emitLiveDebugTableHints({
12436
12459
  event,
12437
12460
  playName: input2.playName,
@@ -12764,6 +12787,11 @@ async function startAndWaitForPlayCompletionByStreamOnce(input2) {
12764
12787
  lastPhase = phase;
12765
12788
  input2.progress.phase(phase);
12766
12789
  }
12790
+ writePlayWaitingHint({
12791
+ event,
12792
+ state,
12793
+ progress: input2.progress
12794
+ });
12767
12795
  printPlayLogLines({
12768
12796
  lines: getLogLinesFromLiveEvent(event),
12769
12797
  status: null,
@@ -26176,9 +26204,14 @@ async function listTools(args) {
26176
26204
  return 0;
26177
26205
  }
26178
26206
  async function searchTools(queryInput, options = {}) {
26179
- const query = queryInput.trim();
26180
- if (!query) {
26181
- console.error("Usage: deepline tools search <query> [--json]");
26207
+ const query = queryInput?.trim() ?? "";
26208
+ const hasStructuredSearch = Boolean(
26209
+ options.categories?.trim() || options.searchTerms?.trim()
26210
+ );
26211
+ if (!query && !hasStructuredSearch) {
26212
+ console.error(
26213
+ "Usage: deepline tools search [query] --categories <categories> [--search_terms <terms>] [--json]"
26214
+ );
26182
26215
  return 1;
26183
26216
  }
26184
26217
  const client2 = new DeeplineClient();
@@ -26414,7 +26447,7 @@ Examples:
26414
26447
  includeSearchDebug: Boolean(options.includeSearchDebug)
26415
26448
  });
26416
26449
  });
26417
- addToolSearchCommand(tools.command("search <query>"));
26450
+ addToolSearchCommand(tools.command("search [query]"));
26418
26451
  tools.command("grep <query>").description(
26419
26452
  "Literal grep over tool ids, descriptions, categories, and input fields."
26420
26453
  ).addHelpText(
@@ -27074,6 +27107,28 @@ function samplePayload(samples, key) {
27074
27107
  function commandEnvelopeFromRawResponse(rawResponse) {
27075
27108
  return isRecord8(rawResponse) ? { ...rawResponse } : { status: "completed", result: rawResponse };
27076
27109
  }
27110
+ function apifySyncRecoveryNext(rawResponse) {
27111
+ if (!isRecord8(rawResponse) || rawResponse.status !== "running") return null;
27112
+ const toolResponse = recordField2(rawResponse, "toolResponse");
27113
+ const raw = recordField2(toolResponse, "raw");
27114
+ if (raw.state !== "awaiting_apify") return null;
27115
+ const next = recordField2(raw, "next");
27116
+ const getActorRun = recordField2(next, "getActorRun");
27117
+ const getActorRunTool = stringField2(getActorRun, "tool");
27118
+ const getActorRunPayload = recordField2(getActorRun, "payload");
27119
+ if (!getActorRunTool || Object.keys(getActorRunPayload).length === 0) {
27120
+ return null;
27121
+ }
27122
+ const getDatasetItems = recordField2(next, "getDatasetItems");
27123
+ const getDatasetItemsTool = stringField2(getDatasetItems, "tool");
27124
+ const getDatasetItemsPayload = recordField2(getDatasetItems, "payload");
27125
+ return {
27126
+ getActorRun: `deepline tools execute ${getActorRunTool} --input ${shellQuote4(JSON.stringify(getActorRunPayload))} --json`,
27127
+ ...getDatasetItemsTool && Object.keys(getDatasetItemsPayload).length > 0 ? {
27128
+ getDatasetItems: `deepline tools execute ${getDatasetItemsTool} --input ${shellQuote4(JSON.stringify(getDatasetItemsPayload))} --json`
27129
+ } : {}
27130
+ };
27131
+ }
27077
27132
  function listExtractorPathsFromUsageGuidance(tool) {
27078
27133
  const toolExecutionResult = tool.usageGuidance?.toolExecutionResult;
27079
27134
  const extractedLists = Array.isArray(toolExecutionResult?.extractedLists) ? toolExecutionResult.extractedLists : isRecord8(toolExecutionResult?.extractedLists) ? Object.values(toolExecutionResult.extractedLists) : [];
@@ -27319,6 +27374,7 @@ export default definePlay(${JSON.stringify(playName)}, async (ctx) => {
27319
27374
  }
27320
27375
  function buildToolExecuteBaseEnvelope(input2) {
27321
27376
  const envelope = commandEnvelopeFromRawResponse(input2.rawResponse);
27377
+ const apifyRecovery = apifySyncRecoveryNext(input2.rawResponse);
27322
27378
  const summaryEntries = Object.entries(input2.summary);
27323
27379
  const outputPreview = input2.listConversion ? {
27324
27380
  kind: "list",
@@ -27342,6 +27398,14 @@ function buildToolExecuteBaseEnvelope(input2) {
27342
27398
  label: "next",
27343
27399
  command: "move starter script into a project folder and expand it into a Deepline play"
27344
27400
  }
27401
+ ] : apifyRecovery ? [
27402
+ { label: "check Apify run", command: apifyRecovery.getActorRun },
27403
+ ...apifyRecovery.getDatasetItems ? [
27404
+ {
27405
+ label: "get Apify dataset items",
27406
+ command: apifyRecovery.getDatasetItems
27407
+ }
27408
+ ] : []
27345
27409
  ] : [];
27346
27410
  return {
27347
27411
  ...envelope,
@@ -27349,6 +27413,7 @@ function buildToolExecuteBaseEnvelope(input2) {
27349
27413
  ...summaryEntries.length > 0 ? { summary: input2.summary } : {},
27350
27414
  next: {
27351
27415
  inspect: inspectCommand,
27416
+ ...apifyRecovery ?? {},
27352
27417
  playDebugging: "When fixing a play getter, inspect returned dataset handles with runs get and export rows with runs export; do not copy CLI preview paths blindly.",
27353
27418
  ...input2.listConversion ? {
27354
27419
  expandToPlay: "Use stable map and step keys so reruns are idempotent: completed rows are reused, and only missing or stale work runs again.",
@@ -27369,7 +27434,9 @@ function buildToolExecuteBaseEnvelope(input2) {
27369
27434
  ] : [
27370
27435
  {
27371
27436
  title: "result",
27372
- lines: summaryEntries.length > 0 ? summaryEntries.map(
27437
+ lines: apifyRecovery ? [
27438
+ "Apify is still running. Run the follow-up command(s) below."
27439
+ ] : summaryEntries.length > 0 ? summaryEntries.map(
27373
27440
  ([key, value]) => `${key}=${String(value)}`
27374
27441
  ) : [JSON.stringify(input2.rawResponse, null, 2)]
27375
27442
  }
package/dist/index.d.mts CHANGED
@@ -3128,7 +3128,7 @@ interface PlayCallOptions {
3128
3128
  * sqlListeners: [
3129
3129
  * {
3130
3130
  * id: 'jobs',
3131
- * tool: 'tamradar.company_radar',
3131
+ * tool: 'deepline_native.company_radar',
3132
3132
  * stream: 'company_job_openings',
3133
3133
  * operations: ['INSERT'],
3134
3134
  * },
@@ -3202,7 +3202,7 @@ type SqlListenerWhere = {
3202
3202
  type SqlListenerDeclaration = {
3203
3203
  /** Short id unique inside this play. Deepline stores it as playName.id. */
3204
3204
  id: string;
3205
- /** Modeled monitor tool id, for example "tamradar.company_radar". */
3205
+ /** Modeled monitor tool id, for example "deepline_native.company_radar". */
3206
3206
  tool: string;
3207
3207
  /** Stream key exposed by the modeled monitor tool, for example "company_job_openings". */
3208
3208
  stream: string;
package/dist/index.d.ts CHANGED
@@ -3128,7 +3128,7 @@ interface PlayCallOptions {
3128
3128
  * sqlListeners: [
3129
3129
  * {
3130
3130
  * id: 'jobs',
3131
- * tool: 'tamradar.company_radar',
3131
+ * tool: 'deepline_native.company_radar',
3132
3132
  * stream: 'company_job_openings',
3133
3133
  * operations: ['INSERT'],
3134
3134
  * },
@@ -3202,7 +3202,7 @@ type SqlListenerWhere = {
3202
3202
  type SqlListenerDeclaration = {
3203
3203
  /** Short id unique inside this play. Deepline stores it as playName.id. */
3204
3204
  id: string;
3205
- /** Modeled monitor tool id, for example "tamradar.company_radar". */
3205
+ /** Modeled monitor tool id, for example "deepline_native.company_radar". */
3206
3206
  tool: string;
3207
3207
  /** Stream key exposed by the modeled monitor tool, for example "company_job_openings". */
3208
3208
  stream: string;
package/dist/index.js CHANGED
@@ -424,10 +424,10 @@ var SDK_RELEASE = {
424
424
  // 0.1.175 ships loud `deepline enrich` empty-waterfall reporting.
425
425
  // 0.1.220 deprecates SDK CLI versions below 0.1.219 and updates them
426
426
  // automatically without blocking their current command.
427
- version: "0.1.227",
427
+ version: "0.1.228",
428
428
  apiContract: "2026-06-dataset-handle-results-hard-cutover",
429
429
  supportPolicy: {
430
- latest: "0.1.227",
430
+ latest: "0.1.228",
431
431
  minimumSupported: "0.1.53",
432
432
  deprecatedBelow: "0.1.219",
433
433
  commandMinimumSupported: [
@@ -1490,8 +1490,9 @@ function normalizePlayRunLifecycleStatus(value) {
1490
1490
  return "running";
1491
1491
  case "running":
1492
1492
  case "started":
1493
- case "waiting":
1494
1493
  return "running";
1494
+ case "waiting":
1495
+ return "waiting";
1495
1496
  case "completed":
1496
1497
  case "complete":
1497
1498
  case "succeeded":
@@ -2265,8 +2266,16 @@ function chunkRegisterPlayArtifacts(artifacts) {
2265
2266
  }
2266
2267
  return chunks;
2267
2268
  }
2268
- function resolveToolExecuteTimeoutMs(toolId) {
2269
+ var APIFY_SYNC_DEFAULT_TIMEOUT_MS = 3e5;
2270
+ var APIFY_SYNC_RESPONSE_GRACE_MS = 9e4;
2271
+ function resolveToolExecuteTimeoutMs(toolId, input) {
2269
2272
  const normalized = toolId.trim().toLowerCase();
2273
+ if (normalized === "apify_run_actor_sync") {
2274
+ const requestedTimeoutMs = input.timeoutMs ?? APIFY_SYNC_DEFAULT_TIMEOUT_MS;
2275
+ if (typeof requestedTimeoutMs === "number" && Number.isFinite(requestedTimeoutMs) && requestedTimeoutMs > 0) {
2276
+ return Math.floor(requestedTimeoutMs) + APIFY_SYNC_RESPONSE_GRACE_MS;
2277
+ }
2278
+ }
2270
2279
  return normalized === "deeplineagent" || normalized === "deeplineagent_deeplineagent" || normalized === "ai_inference" || normalized === "deeplineagent_ai_inference" || normalized === "aiinference" ? DEEPLINEAGENT_EXECUTE_TIMEOUT_MS : void 0;
2271
2280
  }
2272
2281
  var RUNS_FAILED_LOG_LIMIT = 20;
@@ -2766,7 +2775,7 @@ var DeeplineClient = class {
2766
2775
  headers,
2767
2776
  {
2768
2777
  forbiddenAsApiError: true,
2769
- timeout: options?.timeout ?? resolveToolExecuteTimeoutMs(toolId),
2778
+ timeout: options?.timeout ?? resolveToolExecuteTimeoutMs(toolId, input),
2770
2779
  maxRetries: options?.maxRetries ?? 0,
2771
2780
  exactUrlOnly: true
2772
2781
  }
package/dist/index.mjs CHANGED
@@ -354,10 +354,10 @@ var SDK_RELEASE = {
354
354
  // 0.1.175 ships loud `deepline enrich` empty-waterfall reporting.
355
355
  // 0.1.220 deprecates SDK CLI versions below 0.1.219 and updates them
356
356
  // automatically without blocking their current command.
357
- version: "0.1.227",
357
+ version: "0.1.228",
358
358
  apiContract: "2026-06-dataset-handle-results-hard-cutover",
359
359
  supportPolicy: {
360
- latest: "0.1.227",
360
+ latest: "0.1.228",
361
361
  minimumSupported: "0.1.53",
362
362
  deprecatedBelow: "0.1.219",
363
363
  commandMinimumSupported: [
@@ -1420,8 +1420,9 @@ function normalizePlayRunLifecycleStatus(value) {
1420
1420
  return "running";
1421
1421
  case "running":
1422
1422
  case "started":
1423
- case "waiting":
1424
1423
  return "running";
1424
+ case "waiting":
1425
+ return "waiting";
1425
1426
  case "completed":
1426
1427
  case "complete":
1427
1428
  case "succeeded":
@@ -2195,8 +2196,16 @@ function chunkRegisterPlayArtifacts(artifacts) {
2195
2196
  }
2196
2197
  return chunks;
2197
2198
  }
2198
- function resolveToolExecuteTimeoutMs(toolId) {
2199
+ var APIFY_SYNC_DEFAULT_TIMEOUT_MS = 3e5;
2200
+ var APIFY_SYNC_RESPONSE_GRACE_MS = 9e4;
2201
+ function resolveToolExecuteTimeoutMs(toolId, input) {
2199
2202
  const normalized = toolId.trim().toLowerCase();
2203
+ if (normalized === "apify_run_actor_sync") {
2204
+ const requestedTimeoutMs = input.timeoutMs ?? APIFY_SYNC_DEFAULT_TIMEOUT_MS;
2205
+ if (typeof requestedTimeoutMs === "number" && Number.isFinite(requestedTimeoutMs) && requestedTimeoutMs > 0) {
2206
+ return Math.floor(requestedTimeoutMs) + APIFY_SYNC_RESPONSE_GRACE_MS;
2207
+ }
2208
+ }
2200
2209
  return normalized === "deeplineagent" || normalized === "deeplineagent_deeplineagent" || normalized === "ai_inference" || normalized === "deeplineagent_ai_inference" || normalized === "aiinference" ? DEEPLINEAGENT_EXECUTE_TIMEOUT_MS : void 0;
2201
2210
  }
2202
2211
  var RUNS_FAILED_LOG_LIMIT = 20;
@@ -2696,7 +2705,7 @@ var DeeplineClient = class {
2696
2705
  headers,
2697
2706
  {
2698
2707
  forbiddenAsApiError: true,
2699
- timeout: options?.timeout ?? resolveToolExecuteTimeoutMs(toolId),
2708
+ timeout: options?.timeout ?? resolveToolExecuteTimeoutMs(toolId, input),
2700
2709
  maxRetries: options?.maxRetries ?? 0,
2701
2710
  exactUrlOnly: true
2702
2711
  }