deepline 0.1.109 → 0.1.111

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.
Files changed (34) hide show
  1. package/dist/cli/index.js +2634 -1532
  2. package/dist/cli/index.mjs +2547 -1451
  3. package/dist/index.d.mts +21 -14
  4. package/dist/index.d.ts +21 -14
  5. package/dist/index.js +97 -23
  6. package/dist/index.mjs +97 -23
  7. package/dist/repo/apps/play-runner-workers/src/coordinator-entry.ts +192 -121
  8. package/dist/repo/apps/play-runner-workers/src/entry.ts +254 -65
  9. package/dist/repo/apps/play-runner-workers/src/runtime/receipts.ts +18 -27
  10. package/dist/repo/apps/play-runner-workers/src/workflow-instance-create.ts +44 -0
  11. package/dist/repo/apps/play-runner-workers/src/workflow-retry.ts +7 -11
  12. package/dist/repo/sdk/src/client.ts +35 -12
  13. package/dist/repo/sdk/src/errors.ts +2 -2
  14. package/dist/repo/sdk/src/http.ts +87 -7
  15. package/dist/repo/sdk/src/play.ts +1 -1
  16. package/dist/repo/sdk/src/plays/bundle-play-file.ts +5 -1
  17. package/dist/repo/sdk/src/release.ts +13 -10
  18. package/dist/repo/sdk/src/tool-output.ts +2 -2
  19. package/dist/repo/sdk/src/types.ts +9 -6
  20. package/dist/repo/shared_libs/play-runtime/fullenrich-batching.ts +229 -0
  21. package/dist/repo/shared_libs/play-runtime/governor/policy.ts +1 -1
  22. package/dist/repo/shared_libs/play-runtime/play-runtime-batching-registry.ts +20 -0
  23. package/dist/repo/shared_libs/play-runtime/run-failure.ts +20 -12
  24. package/dist/repo/shared_libs/play-runtime/run-ledger.ts +147 -70
  25. package/dist/repo/shared_libs/play-runtime/scheduler-backend.ts +6 -2
  26. package/dist/repo/shared_libs/play-runtime/secret-redaction.ts +15 -0
  27. package/dist/repo/shared_libs/play-runtime/work-receipts.ts +1 -0
  28. package/dist/repo/shared_libs/plays/bundling/index.ts +193 -21
  29. package/dist/repo/shared_libs/plays/static-pipeline.ts +1 -3
  30. package/dist/repo/shared_libs/security/outbound-url-policy.ts +238 -0
  31. package/dist/repo/shared_libs/security/safe-fetch.ts +118 -0
  32. package/dist/viewer/viewer.css +617 -0
  33. package/dist/viewer/viewer.js +1496 -0
  34. package/package.json +5 -1
@@ -0,0 +1,44 @@
1
+ export type WorkflowInstanceLike = {
2
+ id: string;
3
+ };
4
+
5
+ export type WorkflowInstanceCreateResult<T extends WorkflowInstanceLike> = {
6
+ instance: T;
7
+ startMode: 'created' | 'reattached_existing';
8
+ };
9
+
10
+ export function isWorkflowInstanceAlreadyExistsError(error: unknown): boolean {
11
+ const message = error instanceof Error ? error.message : String(error);
12
+ return /instance[._ -]?already[._ -]?exists|Instance already exists/i.test(
13
+ message,
14
+ );
15
+ }
16
+
17
+ export async function createOrAttachWorkflowInstance<
18
+ T extends WorkflowInstanceLike,
19
+ >(input: {
20
+ create: () => Promise<T>;
21
+ getExisting: () => Promise<T>;
22
+ }): Promise<WorkflowInstanceCreateResult<T>> {
23
+ try {
24
+ return { instance: await input.create(), startMode: 'created' };
25
+ } catch (error) {
26
+ if (!isWorkflowInstanceAlreadyExistsError(error)) {
27
+ throw error;
28
+ }
29
+ try {
30
+ return {
31
+ instance: await input.getExisting(),
32
+ startMode: 'reattached_existing',
33
+ };
34
+ } catch (attachError) {
35
+ const message =
36
+ attachError instanceof Error
37
+ ? attachError.message
38
+ : String(attachError);
39
+ throw new Error(
40
+ `Workflow instance already exists but could not be reattached: ${message}`,
41
+ );
42
+ }
43
+ }
44
+ }
@@ -1,7 +1,4 @@
1
- import {
2
- isCloudflareDurableObjectCodeUpdatedError,
3
- normalizePlayRunFailure,
4
- } from '../../../shared_libs/play-runtime/run-failure';
1
+ import { normalizePlayRunFailure } from '../../../shared_libs/play-runtime/run-failure';
5
2
 
6
3
  export const PLATFORM_DEPLOY_WORKFLOW_RETRY_LIMIT = 1;
7
4
 
@@ -26,25 +23,24 @@ export function decideWorkflowPlatformRetry(input: {
26
23
  if (!input.error) {
27
24
  return { action: 'fail', reason: null, message: null };
28
25
  }
29
- const retryablePlatformReset = isCloudflareDurableObjectCodeUpdatedError(
30
- input.error,
31
- );
26
+ const failure = normalizePlayRunFailure(input.error);
27
+ const retryablePlatformReset = failure.code === 'PLATFORM_DEPLOY_INTERRUPTED';
32
28
  if (
33
29
  retryablePlatformReset &&
34
30
  input.retryAttempts < PLATFORM_DEPLOY_WORKFLOW_RETRY_LIMIT
35
31
  ) {
36
32
  return {
37
33
  action: 'retry',
38
- reason: 'cloudflare_durable_object_code_updated',
34
+ reason: 'cloudflare_durable_object_reset',
39
35
  nextAttempt: input.retryAttempts + 1,
40
- message: normalizePlayRunFailure(input.error).message,
36
+ message: failure.message,
41
37
  };
42
38
  }
43
39
  return {
44
40
  action: 'fail',
45
41
  reason: retryablePlatformReset
46
- ? 'cloudflare_durable_object_code_updated_retry_exhausted'
42
+ ? 'cloudflare_durable_object_reset_retry_exhausted'
47
43
  : null,
48
- message: normalizePlayRunFailure(input.error).message,
44
+ message: failure.message,
49
45
  };
50
46
  }
@@ -413,11 +413,14 @@ export type BillingPlanEntry = {
413
413
  };
414
414
 
415
415
  /** One usage metric published in the billing catalog. */
416
- export type BillingMetricEntry = {
416
+ export type BillingMeterEntry = {
417
417
  id: string;
418
418
  name: string;
419
419
  };
420
420
 
421
+ /** @deprecated Use BillingMeterEntry. Retained for wire/API alias compatibility. */
422
+ export type BillingMetricEntry = BillingMeterEntry;
423
+
421
424
  /** The caller's active plan as reported by the plans endpoint. */
422
425
  export type BillingActivePlan = {
423
426
  plan_family_id: string;
@@ -440,6 +443,8 @@ export type BillingPlansResult = {
440
443
  catalog_version: string;
441
444
  active_plan: BillingActivePlan;
442
445
  plans: BillingPlanEntry[];
446
+ meters: BillingMeterEntry[];
447
+ /** @deprecated Use meters. Retained for installed SDK compatibility. */
443
448
  metrics: BillingMetricEntry[];
444
449
  };
445
450
 
@@ -1075,12 +1080,12 @@ export class DeeplineClient {
1075
1080
  * Returns everything from {@link ToolDefinition} plus pricing info, sample
1076
1081
  * inputs/outputs, failure modes, and cost estimates.
1077
1082
  *
1078
- * @param toolId - Tool identifier (e.g. `"apollo_people_search"`)
1083
+ * @param toolId - Tool identifier (e.g. `"dropleads_search_people"`)
1079
1084
  * @returns Full tool metadata
1080
1085
  *
1081
1086
  * @example
1082
1087
  * ```typescript
1083
- * const meta = await client.getTool('apollo_people_search');
1088
+ * const meta = await client.getTool('dropleads_search_people');
1084
1089
  * console.log(`Cost: ${meta.estimatedCreditsRange} credits`);
1085
1090
  * console.log(`Input schema:`, meta.inputSchema);
1086
1091
  * ```
@@ -1120,6 +1125,7 @@ export class DeeplineClient {
1120
1125
  `/api/v2/integrations/${encodeURIComponent(toolId)}/execute`,
1121
1126
  { payload: input },
1122
1127
  headers,
1128
+ { forbiddenAsApiError: true },
1123
1129
  );
1124
1130
  }
1125
1131
 
@@ -1228,7 +1234,7 @@ export class DeeplineClient {
1228
1234
  ? { waitForCompletionMs: request.waitForCompletionMs }
1229
1235
  : {}),
1230
1236
  // Profile selection is the API's job, not the CLI's. The server
1231
- // hardcodes workers_edge as the default; tests that want a
1237
+ // defaults to workers_edge; tests and runtime probes that want a
1232
1238
  // different profile pass `request.profile` explicitly.
1233
1239
  ...(request.profile ? { profile: request.profile } : {}),
1234
1240
  },
@@ -1338,10 +1344,15 @@ export class DeeplineClient {
1338
1344
  sourceFiles: input.sourceFiles,
1339
1345
  artifact: input.artifact,
1340
1346
  }));
1341
- return this.http.post('/api/v2/plays/artifacts', {
1342
- ...input,
1343
- compilerManifest,
1344
- });
1347
+ return this.http.post(
1348
+ '/api/v2/plays/artifacts',
1349
+ {
1350
+ ...input,
1351
+ compilerManifest,
1352
+ },
1353
+ undefined,
1354
+ { forbiddenAsApiError: true, retryApiErrors: true },
1355
+ );
1345
1356
  }
1346
1357
 
1347
1358
  /**
@@ -1379,7 +1390,12 @@ export class DeeplineClient {
1379
1390
  }>;
1380
1391
  }> {
1381
1392
  if (artifacts.length === 0) {
1382
- return this.http.post('/api/v2/plays/artifacts', { artifacts });
1393
+ return this.http.post(
1394
+ '/api/v2/plays/artifacts',
1395
+ { artifacts },
1396
+ undefined,
1397
+ { forbiddenAsApiError: true, retryApiErrors: true },
1398
+ );
1383
1399
  }
1384
1400
  const compiledArtifacts = await mapWithConcurrency(
1385
1401
  artifacts,
@@ -1414,9 +1430,14 @@ export class DeeplineClient {
1414
1430
  triggerMetadata?: unknown;
1415
1431
  triggerBindings?: unknown;
1416
1432
  }>;
1417
- }>('/api/v2/plays/artifacts', {
1418
- artifacts: chunk,
1419
- }),
1433
+ }>(
1434
+ '/api/v2/plays/artifacts',
1435
+ {
1436
+ artifacts: chunk,
1437
+ },
1438
+ undefined,
1439
+ { forbiddenAsApiError: true, retryApiErrors: true },
1440
+ ),
1420
1441
  );
1421
1442
  }
1422
1443
  return {
@@ -2446,6 +2467,8 @@ export class DeeplineClient {
2446
2467
  return this.http.post<PublishPlayVersionResult>(
2447
2468
  `/api/v2/plays/${encodedName}/live`,
2448
2469
  request,
2470
+ undefined,
2471
+ { forbiddenAsApiError: true },
2449
2472
  );
2450
2473
  }
2451
2474
 
@@ -10,7 +10,7 @@
10
10
  *
11
11
  * const client = new DeeplineClient();
12
12
  * try {
13
- * await client.executeTool('apollo_people_search', { query: 'cto' });
13
+ * await client.executeTool('dropleads_search_people', { query: 'cto' });
14
14
  * } catch (err) {
15
15
  * if (err instanceof AuthError) {
16
16
  * console.error('Bad API key — run: deepline auth register');
@@ -77,7 +77,7 @@ export class AuthError extends DeeplineError {
77
77
  * import { RateLimitError } from 'deepline';
78
78
  *
79
79
  * try {
80
- * await client.executeTool('apollo_people_search', { query: 'cto' });
80
+ * await client.executeTool('dropleads_search_people', { query: 'cto' });
81
81
  * } catch (err) {
82
82
  * if (err instanceof RateLimitError) {
83
83
  * console.log(`Retry after ${err.retryAfterMs}ms`);
@@ -35,6 +35,8 @@ import {
35
35
  } from '../../shared_libs/play-runtime/coordinator-headers.js';
36
36
 
37
37
  const MAX_DIAGNOSTIC_HEADER_LENGTH = 120;
38
+ const COWORK_NETWORK_HINT =
39
+ 'Claude Cowork appears to be running Deepline in a network-restricted sandbox. In Claude Desktop, open Settings > Capabilities, turn on Allow network egress, and set Domain allowlist to All domains for the Cowork session.';
38
40
 
39
41
  interface RequestOptions {
40
42
  method?: 'GET' | 'POST' | 'PUT' | 'PATCH' | 'DELETE';
@@ -51,6 +53,11 @@ interface RequestOptions {
51
53
  * {@link AuthError}.
52
54
  */
53
55
  forbiddenAsApiError?: boolean;
56
+ /**
57
+ * Retry HTTP 408/425/5xx JSON API responses. Use only for idempotent requests;
58
+ * most mutating API calls must fail loudly after the first server response.
59
+ */
60
+ retryApiErrors?: boolean;
54
61
  }
55
62
 
56
63
  interface StreamOptions {
@@ -114,6 +121,7 @@ export class HttpClient {
114
121
  'User-Agent': `deepline-ts-sdk/${SDK_VERSION}`,
115
122
  'X-Deepline-Client-Family': 'sdk',
116
123
  'X-Deepline-CLI-Family': 'sdk',
124
+ 'X-Deepline-Agent-Runtime': detectAgentRuntime(),
117
125
  'X-Deepline-CLI-Version': SDK_VERSION,
118
126
  'X-Deepline-SDK-Version': SDK_VERSION,
119
127
  'X-Deepline-API-Contract': SDK_API_CONTRACT,
@@ -270,6 +278,9 @@ export class HttpClient {
270
278
  }
271
279
 
272
280
  if (!response.ok) {
281
+ const retryableApiError =
282
+ options?.retryApiErrors === true &&
283
+ isRetryableApiErrorResponse(response.status);
273
284
  // A 5xx that escaped a Worker can return Cloudflare's default HTML
274
285
  // error page. Never surface raw HTML to CLI users: replace the
275
286
  // message with a structured summary and store a short flag in
@@ -280,7 +291,7 @@ export class HttpClient {
280
291
  response.headers.get('content-type'),
281
292
  );
282
293
  if (htmlError) {
283
- throw new DeeplineError(
294
+ lastError = new DeeplineError(
284
295
  htmlError.message(response.status),
285
296
  response.status,
286
297
  'API_ERROR',
@@ -292,6 +303,11 @@ export class HttpClient {
292
303
  : {}),
293
304
  },
294
305
  );
306
+ if (retryableApiError && attempt < this.config.maxRetries) {
307
+ retryAfterDelayMs = parseOptionalRetryAfter(response);
308
+ break;
309
+ }
310
+ throw lastError;
295
311
  }
296
312
  const errorValue =
297
313
  typeof parsed === 'object' && parsed && 'error' in parsed
@@ -313,9 +329,20 @@ export class HttpClient {
313
329
  'string'
314
330
  ? (parsed as Record<string, string>).message
315
331
  : `HTTP ${response.status}`;
316
- throw new DeeplineError(msg, response.status, 'API_ERROR', {
332
+ const apiErrorCode =
333
+ errorValue &&
334
+ typeof errorValue === 'object' &&
335
+ typeof (errorValue as Record<string, unknown>).code === 'string'
336
+ ? (errorValue as Record<string, string>).code
337
+ : 'API_ERROR';
338
+ lastError = new DeeplineError(msg, response.status, apiErrorCode, {
317
339
  response: parsed,
318
340
  });
341
+ if (retryableApiError && attempt < this.config.maxRetries) {
342
+ retryAfterDelayMs = parseOptionalRetryAfter(response);
343
+ break;
344
+ }
345
+ throw lastError;
319
346
  }
320
347
 
321
348
  return parsed as T;
@@ -341,7 +368,7 @@ export class HttpClient {
341
368
  const errorMessage = lastError?.message
342
369
  ? `Unable to connect to ${baseUrl}. ${lastError.message}`
343
370
  : `Unable to connect to ${baseUrl}. Is the computer able to access the url?`;
344
- throw new DeeplineError(errorMessage);
371
+ throw new DeeplineError(withCoworkNetworkHint(errorMessage));
345
372
  }
346
373
 
347
374
  /**
@@ -427,9 +454,11 @@ export class HttpClient {
427
454
  }
428
455
 
429
456
  throw new DeeplineError(
430
- lastError?.message
431
- ? `Unable to stream from ${this.config.baseUrl}. ${lastError.message}`
432
- : `Unable to stream from ${this.config.baseUrl}.`,
457
+ withCoworkNetworkHint(
458
+ lastError?.message
459
+ ? `Unable to stream from ${this.config.baseUrl}. ${lastError.message}`
460
+ : `Unable to stream from ${this.config.baseUrl}.`,
461
+ ),
433
462
  );
434
463
  }
435
464
 
@@ -444,11 +473,16 @@ export class HttpClient {
444
473
  path: string,
445
474
  body: unknown,
446
475
  headers?: Record<string, string>,
476
+ options?: Pick<
477
+ RequestOptions,
478
+ 'forbiddenAsApiError' | 'retryApiErrors' | 'timeout'
479
+ >,
447
480
  ): Promise<T> {
448
481
  return this.request<T>(path, {
449
482
  method: 'POST',
450
483
  body,
451
484
  headers,
485
+ ...options,
452
486
  });
453
487
  }
454
488
 
@@ -502,6 +536,10 @@ function parseResponseBody(body: string): unknown {
502
536
  }
503
537
  }
504
538
 
539
+ function isRetryableApiErrorResponse(status: number): boolean {
540
+ return status === 408 || status === 425 || (status >= 500 && status < 600);
541
+ }
542
+
505
543
  /**
506
544
  * Detect a raw Cloudflare HTML error page in an error response body.
507
545
  *
@@ -579,6 +617,10 @@ function apiErrorMessage(parsed: unknown, status: number): string {
579
617
 
580
618
  /** Parse the `Retry-After` header as milliseconds. Falls back to 5000ms. */
581
619
  function parseRetryAfter(response: Response): number {
620
+ return parseOptionalRetryAfter(response) ?? 5000;
621
+ }
622
+
623
+ function parseOptionalRetryAfter(response: Response): number | null {
582
624
  const header = response.headers.get('retry-after');
583
625
  if (header) {
584
626
  const seconds = Number(header);
@@ -586,7 +628,7 @@ function parseRetryAfter(response: Response): number {
586
628
  return seconds * 1000;
587
629
  }
588
630
  }
589
- return 5000;
631
+ return null;
590
632
  }
591
633
 
592
634
  /**
@@ -670,3 +712,41 @@ function decodeSseFrame<TEvent extends LiveEventEnvelope>(
670
712
  function sleep(ms: number): Promise<void> {
671
713
  return new Promise((resolve) => setTimeout(resolve, ms));
672
714
  }
715
+
716
+ function isTruthyEnv(name: string): boolean {
717
+ const normalized = process.env[name]?.trim().toLowerCase();
718
+ return ['1', 'true', 'yes', 'on'].includes(normalized ?? '');
719
+ }
720
+
721
+ function isCoworkLikeSandbox(): boolean {
722
+ const pluginMode = isTruthyEnv('DEEPLINE_PLUGIN_MODE');
723
+ const claudeRemote = isTruthyEnv('CLAUDE_CODE_REMOTE');
724
+ const projectDir = Boolean(process.env.CLAUDE_PROJECT_DIR?.trim());
725
+ const pluginRoot = Boolean(process.env.DEEPLINE_PLUGIN_ROOT?.trim());
726
+ const home = process.env.HOME?.trim() ?? '';
727
+ const sessionHome = home.startsWith('/sessions/');
728
+ return (
729
+ (pluginMode || pluginRoot) && (claudeRemote || projectDir || sessionHome)
730
+ );
731
+ }
732
+
733
+ function detectAgentRuntime(): string {
734
+ if (process.env.CODEX_THREAD_ID?.trim()) return 'codex';
735
+ if (isCoworkLikeSandbox()) return 'claude_cowork';
736
+ if (process.env.CLAUDECODE?.trim() === '1') return 'claude_code';
737
+ if (process.env.CLINE_ACTIVE?.trim().toLowerCase() === 'true') return 'cline';
738
+ if (process.env.CURSOR_TRACE_ID?.trim() || process.env.CURSOR_AGENT?.trim()) {
739
+ return 'cursor';
740
+ }
741
+ if (process.env.WINDSURF?.trim() || process.env.CASCADE?.trim()) {
742
+ return 'windsurf';
743
+ }
744
+ return 'unknown';
745
+ }
746
+
747
+ function withCoworkNetworkHint(message: string): string {
748
+ if (!isCoworkLikeSandbox() || message.includes(COWORK_NETWORK_HINT)) {
749
+ return message;
750
+ }
751
+ return `${message}\n${COWORK_NETWORK_HINT}`;
752
+ }
@@ -1456,7 +1456,7 @@ export class DeeplineContext {
1456
1456
  * @example
1457
1457
  * ```typescript
1458
1458
  * const tools = await deepline.tools.list();
1459
- * const meta = await deepline.tools.get('apollo_people_search');
1459
+ * const meta = await deepline.tools.get('dropleads_search_people');
1460
1460
  * const companyLookup = await deepline.tools.execute('test_company_search', { domain: 'stripe.com' });
1461
1461
  * const company = companyLookup.toolResponse.raw;
1462
1462
  * ```
@@ -141,6 +141,9 @@ export function createSdkPlayBundlingAdapter(): PlayBundlingAdapter {
141
141
  sdkWorkersEntryFile: SDK_WORKERS_ENTRY_FILE,
142
142
  workersHarnessEntryFile: WORKERS_HARNESS_ENTRY_FILE,
143
143
  workersHarnessFilesDir: WORKERS_HARNESS_FILES_DIR,
144
+ workersRuntimeFingerprintDirs: [
145
+ resolve(PROJECT_ROOT, 'shared_libs', 'play-runtime'),
146
+ ],
144
147
  discoverPackagedLocalFiles,
145
148
  warnAboutNonDevelopmentBundling,
146
149
  };
@@ -155,7 +158,8 @@ export async function bundlePlayFile(
155
158
  exportName: options.exportName,
156
159
  adapter: createSdkPlayBundlingAdapter(),
157
160
  });
158
- if (result.success) validatePlaySourceFilesHaveNoInlineSecrets(result.sourceFiles);
161
+ if (result.success)
162
+ validatePlaySourceFilesHaveNoInlineSecrets(result.sourceFiles);
159
163
  return result;
160
164
  }
161
165
 
@@ -4,9 +4,11 @@
4
4
  * Ordinary SDK PRs do NOT bump `version` here. Patch version selection
5
5
  * happens at publish time: on push to main, `.github/workflows/sdk-release.yml`
6
6
  * (via `scripts/sdk-release-autobump.ts`) compares the built package against
7
- * the published npm tarball and, when the content changed, stamps the next
8
- * unpublished patch into `version` + `supportPolicy.latest` and publishes it
9
- * in the same run.
7
+ * the latest published npm tarball and, when the content changed, stamps the
8
+ * next unpublished patch into `version` + `supportPolicy.latest` in the CI
9
+ * workspace only and publishes it in the same run. That patch stamp is not
10
+ * committed back to main; production endpoints read npm metadata when they
11
+ * need the newest patch-level SDK/CLI version.
10
12
  *
11
13
  * Edit THIS file by hand only for deliberate release decisions:
12
14
  * - minor/major version bumps (set `version` and `supportPolicy.latest`),
@@ -23,17 +25,18 @@
23
25
  * `scripts/sync-sdk-package-version.ts`, which runs as part of
24
26
  * `bun run sdk:build`.
25
27
  * - `contracts/sdk-api.manifest.json` is regenerated at build time from
26
- * `src/lib/sdk/api-routes.ts` and the apiContract here; the hash in
27
- * `contracts/sdk-api.manifest.hash` is the invariant that lands in git.
28
+ * `src/lib/sdk/api-routes.ts` and the apiContract here; the matching
29
+ * `contracts/sdk-api.manifest.hash` is an ignored local/CI audit artifact.
28
30
  *
29
- * Any drift between this file and the derived locations is a
30
- * `check:sdk-release-readiness` failure with a one-shot fix command.
31
+ * Any drift between release source and derived release locations is a
32
+ * `check:sdk-release-readiness` failure with a one-shot fix command; SDK/API
33
+ * compatibility policy is enforced by `bun run sdk:api-contract:check`.
31
34
  */
32
35
 
33
36
  export type SdkReleaseChannel = 'latest' | 'next' | 'beta';
34
37
 
35
38
  export type SdkSupportPolicy = {
36
- /** Newest published deepline SDK/CLI on npm. */
39
+ /** Checked-in latest policy value; publish-time patch latest is read from npm. */
37
40
  latest: string;
38
41
  /**
39
42
  * Anything strictly below this returns `status: "unsupported"` from
@@ -96,10 +99,10 @@ export const SDK_RELEASE = {
96
99
  // skill on the sdk sync surface, and the people-search-to-email prebuilt.
97
100
  // 0.1.108 ships explicit dataset column/tool recompute policy and removes
98
101
  // the SDK enrich generator's one-second stale policy.
99
- version: '0.1.109',
102
+ version: '0.1.111',
100
103
  apiContract: '2026-06-dataset-column-cell-stale-hard-cutover',
101
104
  supportPolicy: {
102
- latest: '0.1.109',
105
+ latest: '0.1.111',
103
106
  minimumSupported: '0.1.53',
104
107
  deprecatedBelow: '0.1.53',
105
108
  commandMinimumSupported: [
@@ -203,8 +203,8 @@ function findBestArrayCandidate(
203
203
  *
204
204
  * @example Using configured paths (from tool metadata)
205
205
  * ```typescript
206
- * const meta = await client.getTool('apollo_people_search');
207
- * const result = await client.executeTool('apollo_people_search', { query: 'cto' });
206
+ * const meta = await client.getTool('dropleads_search_people');
207
+ * const result = await client.executeTool('dropleads_search_people', { query: 'cto' });
208
208
  *
209
209
  * const list = tryConvertToList(result, {
210
210
  * listExtractorPaths: meta.listExtractorPaths,
@@ -138,9 +138,9 @@ export type {
138
138
  * schema, examples, pricing, and extraction guidance before executing.
139
139
  */
140
140
  export interface ToolDefinition {
141
- /** Unique tool identifier used in API calls (e.g. `"apollo_people_search"`). */
141
+ /** Unique tool identifier used in API calls (e.g. `"dropleads_search_people"`). */
142
142
  toolId: string;
143
- /** Provider that backs this tool (e.g. `"apollo"`, `"hunter"`, `"test"`). */
143
+ /** Provider that backs this tool (e.g. `"hunter"`, `"dropleads"`, `"test"`). */
144
144
  provider: string;
145
145
  /** Human-readable name for display. */
146
146
  displayName: string;
@@ -154,6 +154,8 @@ export interface ToolDefinition {
154
154
  operationId?: string;
155
155
  /** Alternative names that resolve to this tool. */
156
156
  operationAliases?: string[];
157
+ /** Explicit globally runnable play reference for play-backed catalog entries. */
158
+ playReference?: `prebuilt/${string}`;
157
159
  /** Whether detailed input schema is available from `tools describe`. */
158
160
  hasInputSchema?: boolean;
159
161
  /** Whether detailed output schema is available from `tools describe`. */
@@ -313,8 +315,8 @@ export interface ToolSearchResult {
313
315
  *
314
316
  * @example
315
317
  * ```typescript
316
- * const meta = await client.getTool('apollo_people_search');
317
- * console.log(meta.displayName); // "Apollo People Search"
318
+ * const meta = await client.getTool('dropleads_search_people');
319
+ * console.log(meta.displayName); // "DropLeads People Search"
318
320
  * console.log(meta.estimatedCreditsRange); // "1-5"
319
321
  * console.log(meta.samples); // { input: {...}, output: {...} }
320
322
  * ```
@@ -933,8 +935,9 @@ export interface StartPlayRunRequest {
933
935
  /** Optionally let the start request wait briefly and return a terminal result. */
934
936
  waitForCompletionMs?: number;
935
937
  /**
936
- * Per-run execution profile override. The server defaults to `workers_edge`;
937
- * tests can pass `local` here. Most callers should leave this unset.
938
+ * Per-run execution profile override. The server defaults to workers_edge;
939
+ * tests and runtime probes can pass a different profile here. Most callers
940
+ * should leave this unset.
938
941
  */
939
942
  profile?: string;
940
943
  }