deepline 0.3.239 → 0.3.240

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.
@@ -1806,6 +1806,15 @@ export type TargetBillingStatusResult = {
1806
1806
  payment_state: string;
1807
1807
  recharge_state: string;
1808
1808
  billing_email?: string | null;
1809
+ /** Omitted when unavailable; null when no address has been saved. */
1810
+ billing_address?: {
1811
+ line1: string | null;
1812
+ line2: string | null;
1813
+ city: string | null;
1814
+ state: string | null;
1815
+ postal_code: string | null;
1816
+ country: string | null;
1817
+ } | null;
1809
1818
  collection_method?: 'charge_automatically' | 'send_invoice';
1810
1819
  payment_access_policy?: 'payment_required' | 'net_30' | 'net_60';
1811
1820
  plan_invoice?: {
@@ -2163,7 +2172,9 @@ export type BillingNamespace = {
2163
2172
  options: TargetBillingPlanTransitionOptions,
2164
2173
  ) => Promise<TargetBillingMutationResult>;
2165
2174
  /** Create a Stripe-hosted billing Portal session. */
2166
- portalSession: () => Promise<{ url: string }>;
2175
+ portalSession: (options?: {
2176
+ flow?: 'customer_update';
2177
+ }) => Promise<{ url: string }>;
2167
2178
  };
2168
2179
 
2169
2180
  function requireTargetBillingIdempotencyKey(value: string): string {
@@ -2713,7 +2724,8 @@ export class DeeplineClient {
2713
2724
  recoverCreditPurchase: (options) =>
2714
2725
  this.recoverTargetBillingCreditPurchase(options),
2715
2726
  transitionPlan: (options) => this.transitionTargetBillingPlan(options),
2716
- portalSession: () => this.createTargetBillingPortalSession(),
2727
+ portalSession: (options) =>
2728
+ this.createTargetBillingPortalSession(options),
2717
2729
  };
2718
2730
  this.workspaces = {
2719
2731
  create: (options) => this.createWorkspace(options),
@@ -6154,11 +6166,18 @@ export class DeeplineClient {
6154
6166
  }
6155
6167
 
6156
6168
  /** Create a Stripe-hosted portal session for payment recovery and invoices. */
6157
- async createTargetBillingPortalSession(): Promise<{ url: string }> {
6169
+ async createTargetBillingPortalSession(options?: {
6170
+ flow?: 'customer_update';
6171
+ }): Promise<{ url: string }> {
6158
6172
  const response = await this.http.post<{
6159
6173
  data: { url: string };
6160
6174
  request_id?: string;
6161
- }>('/api/v2/billing/portal-sessions', {});
6175
+ }>(
6176
+ options?.flow === 'customer_update'
6177
+ ? '/api/v2/billing/portal-sessions?flow=customer_update'
6178
+ : '/api/v2/billing/portal-sessions',
6179
+ {},
6180
+ );
6162
6181
  return response.data;
6163
6182
  }
6164
6183
 
@@ -395,6 +395,11 @@ export class HttpClient {
395
395
  let fetchAttempts = 0;
396
396
  let lastRequestUrl = url;
397
397
  let networkFailedAt: number | undefined;
398
+ let networkPhase:
399
+ | 'before_request'
400
+ | 'retry_wait'
401
+ | 'awaiting_headers'
402
+ | 'reading_body' = 'before_request';
398
403
 
399
404
  const headers = this.authHeaders(options?.headers);
400
405
 
@@ -423,6 +428,7 @@ export class HttpClient {
423
428
  ? backoffMs
424
429
  : Math.max(backoffMs, retryAfterDelayMs);
425
430
  retryAfterDelayMs = null;
431
+ networkPhase = 'retry_wait';
426
432
  try {
427
433
  await sleep(delayMs, options?.signal);
428
434
  } catch (error) {
@@ -450,6 +456,7 @@ export class HttpClient {
450
456
  once: true,
451
457
  });
452
458
 
459
+ networkPhase = 'before_request';
453
460
  try {
454
461
  const requestBody =
455
462
  options?.formData !== undefined
@@ -461,6 +468,7 @@ export class HttpClient {
461
468
  : undefined;
462
469
  fetchAttempts += 1;
463
470
  lastRequestUrl = candidateUrl;
471
+ networkPhase = 'awaiting_headers';
464
472
  const response = await fetch(candidateUrl, {
465
473
  method,
466
474
  headers,
@@ -468,6 +476,7 @@ export class HttpClient {
468
476
  signal: controller.signal,
469
477
  });
470
478
 
479
+ networkPhase = 'reading_body';
471
480
  options?.onResponse?.(response);
472
481
  if (response.status === 404 && options?.allowNotFound) {
473
482
  clearTimeout(timeoutId);
@@ -671,6 +680,7 @@ export class HttpClient {
671
680
  // Elapsed time covers the entire logical request, including retries.
672
681
  elapsedMs: Math.max(0, failedAt - requestStartedAt),
673
682
  attempts: fetchAttempts,
683
+ phase: networkPhase,
674
684
  },
675
685
  };
676
686
  if (options?.toolId) {
@@ -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.239',
203
+ version: '0.3.240',
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: {
@@ -1,3 +1,4 @@
1
+ import { OPENSOSDATA_LOOKUP_CLIENT_TIMEOUT_MS } from '../../shared_libs/integration-contracts/opensosdata/execution-policy.js';
1
2
  import type { ToolResultBilling } from '../../shared_libs/plays/tool-result-types.js';
2
3
  import { resolveTheirstackClientTimeoutMs } from '../../shared_libs/integration-contracts/theirstack/execution-policy.js';
3
4
  import { resolveWaterfallClientTimeoutMs } from '../../shared_libs/integration-contracts/waterfall/execution-policy.js';
@@ -172,6 +173,9 @@ function resolveToolExecuteTimeoutMs(
172
173
  input: Record<string, unknown>,
173
174
  ): number | undefined {
174
175
  const normalized = toolId.trim().toLowerCase();
176
+ if (normalized === 'opensosdata_business_lookup') {
177
+ return OPENSOSDATA_LOOKUP_CLIENT_TIMEOUT_MS;
178
+ }
175
179
  if (normalized === 'apify_run_actor_sync') {
176
180
  const requestedTimeoutMs = input.timeoutMs ?? APIFY_SYNC_DEFAULT_TIMEOUT_MS;
177
181
  if (
@@ -228,6 +228,8 @@ export interface ToolDefinition extends ToolExecutionMetadataFields {
228
228
  outputSchema?: Record<string, unknown>;
229
229
  /** User-facing pricing summary. Internal provider/settlement costs are intentionally omitted. */
230
230
  pricing?: ToolPricingSummary | null;
231
+ /** How to use the tool well: the provider's summary and the tool's own notes. */
232
+ guidance?: { provider?: string; tool?: string };
231
233
  /** Copyable play-runtime guidance for V2 tool execution results. */
232
234
  usageGuidance?: {
233
235
  execute?: string;
@@ -0,0 +1,18 @@
1
+ /** OpenSOSData's single-entity lookup can complete synchronously or poll a 202 job. */
2
+ export const OPENSOSDATA_LOOKUP_REQUEST_TIMEOUT_MS = 120_000;
3
+ export const OPENSOSDATA_POLL_INTERVAL_MS = 3_000;
4
+ export const OPENSOSDATA_POLL_TIMEOUT_MS = 90_000;
5
+
6
+ /**
7
+ * Preserve the provider's existing request and polling windows. A final poll
8
+ * can begin just before the poll window ends, so include that in-flight request
9
+ * as well as route/admission and response overhead. Explicit caller deadlines
10
+ * still take precedence; unrelated tools retain their existing budgets.
11
+ */
12
+ export const OPENSOSDATA_LOOKUP_CLIENT_TIMEOUT_MS =
13
+ 60_000 +
14
+ OPENSOSDATA_LOOKUP_REQUEST_TIMEOUT_MS +
15
+ OPENSOSDATA_POLL_TIMEOUT_MS +
16
+ OPENSOSDATA_POLL_INTERVAL_MS +
17
+ OPENSOSDATA_LOOKUP_REQUEST_TIMEOUT_MS +
18
+ 15_000;
package/dist/cli/index.js CHANGED
@@ -3001,6 +3001,12 @@ function resolveCliCommandContext(inputConfig, requestedScope) {
3001
3001
  };
3002
3002
  }
3003
3003
 
3004
+ // ../integration-contracts/opensosdata/execution-policy.ts
3005
+ var OPENSOSDATA_LOOKUP_REQUEST_TIMEOUT_MS = 12e4;
3006
+ var OPENSOSDATA_POLL_INTERVAL_MS = 3e3;
3007
+ var OPENSOSDATA_POLL_TIMEOUT_MS = 9e4;
3008
+ var OPENSOSDATA_LOOKUP_CLIENT_TIMEOUT_MS = 6e4 + OPENSOSDATA_LOOKUP_REQUEST_TIMEOUT_MS + OPENSOSDATA_POLL_TIMEOUT_MS + OPENSOSDATA_POLL_INTERVAL_MS + OPENSOSDATA_LOOKUP_REQUEST_TIMEOUT_MS + 15e3;
3009
+
3004
3010
  // ../integration-contracts/theirstack/execution-policy.ts
3005
3011
  var THEIRSTACK_SLOW_JOB_SEARCH_PROVIDER_TIMEOUT_MS = 135e3;
3006
3012
  var THEIRSTACK_SLOW_JOB_SEARCH_CLIENT_TIMEOUT_MS = 6e4 + THEIRSTACK_SLOW_JOB_SEARCH_PROVIDER_TIMEOUT_MS + 15e3;
@@ -3151,6 +3157,9 @@ var APIFY_SYNC_DEFAULT_TIMEOUT_MS = 3e5;
3151
3157
  var APIFY_SYNC_RESPONSE_GRACE_MS = 9e4;
3152
3158
  function resolveToolExecuteTimeoutMs(toolId, input2) {
3153
3159
  const normalized = toolId.trim().toLowerCase();
3160
+ if (normalized === "opensosdata_business_lookup") {
3161
+ return OPENSOSDATA_LOOKUP_CLIENT_TIMEOUT_MS;
3162
+ }
3154
3163
  if (normalized === "apify_run_actor_sync") {
3155
3164
  const requestedTimeoutMs = input2.timeoutMs ?? APIFY_SYNC_DEFAULT_TIMEOUT_MS;
3156
3165
  if (typeof requestedTimeoutMs === "number" && Number.isFinite(requestedTimeoutMs) && requestedTimeoutMs > 0) {
@@ -3454,7 +3463,7 @@ var SDK_RELEASE = {
3454
3463
  // getters keep their established compatibility behavior.
3455
3464
  // 0.3.1 deprecated the legacy `deepline enrich` command in favor of Plays.
3456
3465
  // 0.3.90 is the first deliberately versioned SDK release for API v3.
3457
- version: "0.3.239",
3466
+ version: "0.3.240",
3458
3467
  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.",
3459
3468
  packageCapabilities: {
3460
3469
  updatePreferences: 1
@@ -4246,6 +4255,7 @@ var HttpClient = class {
4246
4255
  let fetchAttempts = 0;
4247
4256
  let lastRequestUrl = url;
4248
4257
  let networkFailedAt;
4258
+ let networkPhase = "before_request";
4249
4259
  const headers = this.authHeaders(options?.headers);
4250
4260
  if (options?.body !== void 0) {
4251
4261
  headers["Content-Type"] = "application/json";
@@ -4264,6 +4274,7 @@ var HttpClient = class {
4264
4274
  const backoffMs = Math.min(1e3 * Math.pow(2, attempt - 1), 3e4);
4265
4275
  const delayMs = retryAfterDelayMs === null ? backoffMs : Math.max(backoffMs, retryAfterDelayMs);
4266
4276
  retryAfterDelayMs = null;
4277
+ networkPhase = "retry_wait";
4267
4278
  try {
4268
4279
  await sleep(delayMs, options?.signal);
4269
4280
  } catch (error) {
@@ -4289,16 +4300,19 @@ var HttpClient = class {
4289
4300
  options?.signal?.addEventListener("abort", abortRequest, {
4290
4301
  once: true
4291
4302
  });
4303
+ networkPhase = "before_request";
4292
4304
  try {
4293
4305
  const requestBody = options?.formData !== void 0 ? typeof options.formData === "function" ? options.formData() : options.formData : options?.body !== void 0 ? JSON.stringify(options.body) : void 0;
4294
4306
  fetchAttempts += 1;
4295
4307
  lastRequestUrl = candidateUrl;
4308
+ networkPhase = "awaiting_headers";
4296
4309
  const response = await fetch(candidateUrl, {
4297
4310
  method,
4298
4311
  headers,
4299
4312
  body: requestBody,
4300
4313
  signal: controller.signal
4301
4314
  });
4315
+ networkPhase = "reading_body";
4302
4316
  options?.onResponse?.(response);
4303
4317
  if (response.status === 404 && options?.allowNotFound) {
4304
4318
  clearTimeout(timeoutId);
@@ -4441,7 +4455,8 @@ var HttpClient = class {
4441
4455
  failedAtUtc: new Date(failedAt).toISOString(),
4442
4456
  // Elapsed time covers the entire logical request, including retries.
4443
4457
  elapsedMs: Math.max(0, failedAt - requestStartedAt),
4444
- attempts: fetchAttempts
4458
+ attempts: fetchAttempts,
4459
+ phase: networkPhase
4445
4460
  }
4446
4461
  };
4447
4462
  if (options?.toolId) {
@@ -6340,7 +6355,7 @@ var DeeplineClient = class _DeeplineClient {
6340
6355
  purchaseCredits: (options2) => this.purchaseTargetBillingCredits(options2),
6341
6356
  recoverCreditPurchase: (options2) => this.recoverTargetBillingCreditPurchase(options2),
6342
6357
  transitionPlan: (options2) => this.transitionTargetBillingPlan(options2),
6343
- portalSession: () => this.createTargetBillingPortalSession()
6358
+ portalSession: (options2) => this.createTargetBillingPortalSession(options2)
6344
6359
  };
6345
6360
  this.workspaces = {
6346
6361
  create: (options2) => this.createWorkspace(options2)
@@ -8861,8 +8876,11 @@ var DeeplineClient = class _DeeplineClient {
8861
8876
  );
8862
8877
  }
8863
8878
  /** Create a Stripe-hosted portal session for payment recovery and invoices. */
8864
- async createTargetBillingPortalSession() {
8865
- const response = await this.http.post("/api/v2/billing/portal-sessions", {});
8879
+ async createTargetBillingPortalSession(options) {
8880
+ const response = await this.http.post(
8881
+ options?.flow === "customer_update" ? "/api/v2/billing/portal-sessions?flow=customer_update" : "/api/v2/billing/portal-sessions",
8882
+ {}
8883
+ );
8866
8884
  return response.data;
8867
8885
  }
8868
8886
  /** Create an additional workspace through the durable PAYG workflow. */
@@ -12577,7 +12595,9 @@ async function handleTargetPlanCancellation(options) {
12577
12595
  );
12578
12596
  }
12579
12597
  async function handleTargetPortal(options) {
12580
- const payload = await new DeeplineClient().billing.portalSession();
12598
+ const payload = await new DeeplineClient().billing.portalSession(
12599
+ options.billingAddress ? { flow: "customer_update" } : void 0
12600
+ );
12581
12601
  if (!options.json && !options.noOpen) openInBrowser(payload.url);
12582
12602
  printCommandEnvelope({ ok: true, ...payload }, { json: options.json });
12583
12603
  }
@@ -12864,7 +12884,7 @@ Examples:
12864
12884
  "Invoice recipient when the account has no billing email"
12865
12885
  ).option("--idempotency-key <key>", "Stable retry key").option("--json", "Emit JSON output").action(handleTargetPlan);
12866
12886
  billing.command("cancel-plan").description("Cancel a target subscription at period end, or undo it.").option("--undo", "Undo a pending period-end cancellation").option("--idempotency-key <key>", "Stable retry key").option("--json", "Emit JSON output").action(handleTargetPlanCancellation);
12867
- billing.command("portal").description("Open the Stripe-hosted billing recovery portal.").option("--no-open", "Print the URL without opening a browser").option("--json", "Emit JSON output").action(handleTargetPortal);
12887
+ billing.command("portal").description("Open the Stripe-hosted billing recovery portal.").option("--billing-address", "Open the billing address editor directly").option("--no-open", "Print the URL without opening a browser").option("--json", "Emit JSON output").action(handleTargetPortal);
12868
12888
  billing.command("plans").description("Show published plans and the plan you are on.").addHelpText(
12869
12889
  "after",
12870
12890
  `
@@ -43168,7 +43188,7 @@ function classifyNetworkFailure(error) {
43168
43188
  if (combined.includes("aborterror") || combined.includes("timeout") || combined.includes("timed out") || combined.includes("etimedout")) {
43169
43189
  return "network_timeout";
43170
43190
  }
43171
- if (combined.includes("enotfound") || combined.includes("eai_again") || combined.includes("name or service not known") || combined.includes("temporary failure in name resolution")) {
43191
+ if (combined.includes("enotfound") || combined.includes("eai_again") || combined.includes("getaddrinfo") || combined.includes("name or service not known") || combined.includes("temporary failure in name resolution")) {
43172
43192
  return "network_dns_resolution_failed";
43173
43193
  }
43174
43194
  if (combined.includes("econnrefused") || combined.includes("connection refused")) {
@@ -43191,6 +43211,14 @@ function classifyNetworkFailure(error) {
43191
43211
  return "network_error";
43192
43212
  }
43193
43213
  function classifyNetworkCauseCategory(error) {
43214
+ const seen = /* @__PURE__ */ new Set();
43215
+ let cause = error;
43216
+ while (cause && typeof cause === "object" && !seen.has(cause)) {
43217
+ seen.add(cause);
43218
+ const record3 = cause;
43219
+ if (record3.code === "UND_ERR_CONNECT_TIMEOUT") return "connect_timeout";
43220
+ cause = record3.cause;
43221
+ }
43194
43222
  switch (classifyNetworkFailure(error)) {
43195
43223
  case "network_dns_resolution_failed":
43196
43224
  return "dns";
@@ -43199,7 +43227,7 @@ function classifyNetworkCauseCategory(error) {
43199
43227
  case "network_connection_reset":
43200
43228
  return "reset";
43201
43229
  case "network_timeout":
43202
- return "connect_timeout";
43230
+ return "timeout";
43203
43231
  default:
43204
43232
  return "unknown";
43205
43233
  }
@@ -43365,8 +43393,44 @@ function resolveSdkCliFailureExitCode(error) {
43365
43393
  function resolvedFailureKind(input2) {
43366
43394
  return input2.error === void 0 ? "command_exit" : "uncaught_exception";
43367
43395
  }
43396
+ function safeRequestDiagnostics(error) {
43397
+ if (!(error instanceof DeeplineError)) return null;
43398
+ const request = error.details?.request;
43399
+ if (!request || typeof request !== "object" || Array.isArray(request))
43400
+ return null;
43401
+ const value = request;
43402
+ const result = {};
43403
+ if (typeof value.phase === "string" && [
43404
+ "before_request",
43405
+ "retry_wait",
43406
+ "awaiting_headers",
43407
+ "reading_body"
43408
+ ].includes(value.phase))
43409
+ result.phase = value.phase;
43410
+ if (typeof value.method === "string" && /^(GET|HEAD|POST|PUT|PATCH|DELETE|OPTIONS)$/.test(value.method))
43411
+ result.method = value.method;
43412
+ if (typeof value.url === "string") {
43413
+ try {
43414
+ const url = new URL(value.url);
43415
+ if (url.protocol === "https:" || url.protocol === "http:") {
43416
+ result.url = redactFailureText(`${url.origin}${url.pathname}`, 1e3);
43417
+ }
43418
+ } catch {
43419
+ }
43420
+ }
43421
+ if (typeof value.failedAtUtc === "string" && Number.isFinite(Date.parse(value.failedAtUtc))) {
43422
+ result.failedAtUtc = new Date(value.failedAtUtc).toISOString();
43423
+ }
43424
+ for (const key of ["elapsedMs", "attempts"]) {
43425
+ const number = value[key];
43426
+ if (typeof number === "number" && Number.isSafeInteger(number) && number >= 0)
43427
+ result[key] = number;
43428
+ }
43429
+ return Object.keys(result).length > 0 ? result : null;
43430
+ }
43368
43431
  function buildFailureReport(input2) {
43369
43432
  const durationMs = Math.max(0, Date.now() - input2.startedAtMs);
43433
+ const request = safeRequestDiagnostics(input2.error);
43370
43434
  const failureKind = resolvedFailureKind({
43371
43435
  exitCode: input2.exitCode,
43372
43436
  error: input2.error
@@ -43391,6 +43455,7 @@ function buildFailureReport(input2) {
43391
43455
  base_url: redactFailureText(input2.baseUrl, 400),
43392
43456
  command_summary: sanitizeCommand(input2.argv),
43393
43457
  environment: buildEnvironmentContext(),
43458
+ ...request ? { request } : {},
43394
43459
  failure_kind: failureKind,
43395
43460
  failure_code: code,
43396
43461
  failure_stage: input2.error === void 0 ? "command_exit" : "cli_main",
@@ -49438,6 +49503,7 @@ function toolContractJsonForDescribe(tool, requestedToolId) {
49438
49503
  const outputSchemaRecord = recordField2(tool, "outputSchema", "output_schema");
49439
49504
  const outputFields = toolOutputFieldsForDisplay(outputSchemaRecord);
49440
49505
  const usageGuidance = recordField2(tool, "usageGuidance", "usage_guidance");
49506
+ const guidance = recordField2(tool, "guidance");
49441
49507
  const toolExecutionResult = recordField2(
49442
49508
  usageGuidance,
49443
49509
  "toolExecutionResult",
@@ -49486,6 +49552,7 @@ function toolContractJsonForDescribe(tool, requestedToolId) {
49486
49552
  displayName: tool.displayName,
49487
49553
  cost: pricing,
49488
49554
  description: tool.description,
49555
+ ...Object.keys(guidance).length > 0 ? { guidance } : {},
49489
49556
  categories: tool.categories,
49490
49557
  ...deprecated ? {
49491
49558
  deprecated: true,
@@ -49636,6 +49703,15 @@ function printMonitorTypeContract(tool, requestedToolId) {
49636
49703
  console.log("");
49637
49704
  console.log(`More: deepline tools get ${toolId} --json`);
49638
49705
  }
49706
+ function toolGuidanceLines(guidance) {
49707
+ const record3 = isRecord9(guidance) ? guidance : {};
49708
+ const toolGuidance = stringField2(record3, "tool");
49709
+ const providerGuidance = stringField2(record3, "provider");
49710
+ return [
49711
+ ...toolGuidance ? [`- This tool: ${toolGuidance}`] : [],
49712
+ ...providerGuidance ? [`- Provider: ${providerGuidance}`] : []
49713
+ ];
49714
+ }
49639
49715
  function printCompactToolContract(tool, requestedToolId) {
49640
49716
  if (isMonitorTypeTool(tool)) {
49641
49717
  printMonitorTypeContract(tool, requestedToolId);
@@ -49657,6 +49733,10 @@ function printCompactToolContract(tool, requestedToolId) {
49657
49733
  if (Array.isArray(contract.categories) && contract.categories.length) {
49658
49734
  console.log(`Tags: ${contract.categories.join(", ")}`);
49659
49735
  }
49736
+ const guidanceLines = toolGuidanceLines(contract.guidance);
49737
+ if (guidanceLines.length > 0) {
49738
+ console.log(["Guidance:", ...guidanceLines].join("\n"));
49739
+ }
49660
49740
  printToolOutputArrayShape(contract);
49661
49741
  printToolExecutionHints(contract);
49662
49742
  if (contract.deprecated === true) {
@@ -50724,6 +50804,7 @@ export default definePlay(${JSON.stringify(playName)}, async (ctx) => {
50724
50804
  }
50725
50805
  function buildToolExecuteBaseEnvelope(input2) {
50726
50806
  const envelope = commandEnvelopeFromRawResponse(input2.rawResponse);
50807
+ const guidanceLines = toolExecuteExitCode(envelope) !== 0 || input2.listExpected === true && !input2.listConversion ? toolGuidanceLines(input2.guidance) : [];
50727
50808
  const warningMessages = extractToolExecutionWarningMessages(
50728
50809
  input2.rawResponse
50729
50810
  );
@@ -50775,6 +50856,7 @@ function buildToolExecuteBaseEnvelope(input2) {
50775
50856
  inspect: inspectCommand,
50776
50857
  ...billingLookup ? { billing: billingLookup } : {},
50777
50858
  ...apifyRecovery ?? {},
50859
+ ...guidanceLines.length > 0 ? { guidance: input2.guidance } : {},
50778
50860
  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.",
50779
50861
  ...input2.listConversion ? {
50780
50862
  expandToPlay: "Use stable map and step keys so reruns are idempotent: completed rows are reused, and only missing or stale work runs again.",
@@ -50802,7 +50884,8 @@ function buildToolExecuteBaseEnvelope(input2) {
50802
50884
  ] : summaryEntries.length > 0 ? summaryEntries.map(
50803
50885
  ([key, value]) => `${key}=${String(value)}`
50804
50886
  ) : [JSON.stringify(input2.rawResponse, null, 2)]
50805
- }
50887
+ },
50888
+ ...guidanceLines.length > 0 ? [{ title: "guidance", lines: guidanceLines }] : []
50806
50889
  ],
50807
50890
  actions
50808
50891
  }
@@ -50974,10 +51057,17 @@ async function executeTool(args) {
50974
51057
  ...idempotencyKey ? { idempotencyKey } : {},
50975
51058
  ...parsed.recoveryTimeoutMs !== void 0 ? { recoveryTimeoutMs: parsed.recoveryTimeoutMs } : {},
50976
51059
  searchRef: recentSearchRef()
51060
+ }).catch((error) => {
51061
+ const guidanceLines = toolGuidanceLines(metadata.guidance);
51062
+ if (guidanceLines.length > 0) {
51063
+ console.error(
51064
+ [`Guidance for ${parsed.toolId}:`, ...guidanceLines].join("\n")
51065
+ );
51066
+ }
51067
+ throw error;
50977
51068
  });
50978
- const listConversion = tryConvertToList(rawResponse, {
50979
- listExtractorPaths: listExtractorPathsFromUsageGuidance(metadata)
50980
- });
51069
+ const listExtractorPaths = listExtractorPathsFromUsageGuidance(metadata);
51070
+ const listConversion = tryConvertToList(rawResponse, { listExtractorPaths });
50981
51071
  const summary = extractSummaryFields(rawResponse);
50982
51072
  const baseEnvelope = buildToolExecuteBaseEnvelope({
50983
51073
  toolId: parsed.toolId,
@@ -50985,7 +51075,9 @@ async function executeTool(args) {
50985
51075
  ...idempotencyKey ? { idempotencyKey } : {},
50986
51076
  rawResponse,
50987
51077
  listConversion,
50988
- summary
51078
+ summary,
51079
+ guidance: metadata.guidance,
51080
+ listExpected: listExtractorPaths.length > 0
50989
51081
  });
50990
51082
  const executeExitCode = toolExecuteExitCode(baseEnvelope);
50991
51083
  const delivered = (() => {
@@ -2996,6 +2996,12 @@ function resolveCliCommandContext(inputConfig, requestedScope) {
2996
2996
  };
2997
2997
  }
2998
2998
 
2999
+ // ../integration-contracts/opensosdata/execution-policy.ts
3000
+ var OPENSOSDATA_LOOKUP_REQUEST_TIMEOUT_MS = 12e4;
3001
+ var OPENSOSDATA_POLL_INTERVAL_MS = 3e3;
3002
+ var OPENSOSDATA_POLL_TIMEOUT_MS = 9e4;
3003
+ var OPENSOSDATA_LOOKUP_CLIENT_TIMEOUT_MS = 6e4 + OPENSOSDATA_LOOKUP_REQUEST_TIMEOUT_MS + OPENSOSDATA_POLL_TIMEOUT_MS + OPENSOSDATA_POLL_INTERVAL_MS + OPENSOSDATA_LOOKUP_REQUEST_TIMEOUT_MS + 15e3;
3004
+
2999
3005
  // ../integration-contracts/theirstack/execution-policy.ts
3000
3006
  var THEIRSTACK_SLOW_JOB_SEARCH_PROVIDER_TIMEOUT_MS = 135e3;
3001
3007
  var THEIRSTACK_SLOW_JOB_SEARCH_CLIENT_TIMEOUT_MS = 6e4 + THEIRSTACK_SLOW_JOB_SEARCH_PROVIDER_TIMEOUT_MS + 15e3;
@@ -3146,6 +3152,9 @@ var APIFY_SYNC_DEFAULT_TIMEOUT_MS = 3e5;
3146
3152
  var APIFY_SYNC_RESPONSE_GRACE_MS = 9e4;
3147
3153
  function resolveToolExecuteTimeoutMs(toolId, input2) {
3148
3154
  const normalized = toolId.trim().toLowerCase();
3155
+ if (normalized === "opensosdata_business_lookup") {
3156
+ return OPENSOSDATA_LOOKUP_CLIENT_TIMEOUT_MS;
3157
+ }
3149
3158
  if (normalized === "apify_run_actor_sync") {
3150
3159
  const requestedTimeoutMs = input2.timeoutMs ?? APIFY_SYNC_DEFAULT_TIMEOUT_MS;
3151
3160
  if (typeof requestedTimeoutMs === "number" && Number.isFinite(requestedTimeoutMs) && requestedTimeoutMs > 0) {
@@ -3449,7 +3458,7 @@ var SDK_RELEASE = {
3449
3458
  // getters keep their established compatibility behavior.
3450
3459
  // 0.3.1 deprecated the legacy `deepline enrich` command in favor of Plays.
3451
3460
  // 0.3.90 is the first deliberately versioned SDK release for API v3.
3452
- version: "0.3.239",
3461
+ version: "0.3.240",
3453
3462
  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.",
3454
3463
  packageCapabilities: {
3455
3464
  updatePreferences: 1
@@ -4241,6 +4250,7 @@ var HttpClient = class {
4241
4250
  let fetchAttempts = 0;
4242
4251
  let lastRequestUrl = url;
4243
4252
  let networkFailedAt;
4253
+ let networkPhase = "before_request";
4244
4254
  const headers = this.authHeaders(options?.headers);
4245
4255
  if (options?.body !== void 0) {
4246
4256
  headers["Content-Type"] = "application/json";
@@ -4259,6 +4269,7 @@ var HttpClient = class {
4259
4269
  const backoffMs = Math.min(1e3 * Math.pow(2, attempt - 1), 3e4);
4260
4270
  const delayMs = retryAfterDelayMs === null ? backoffMs : Math.max(backoffMs, retryAfterDelayMs);
4261
4271
  retryAfterDelayMs = null;
4272
+ networkPhase = "retry_wait";
4262
4273
  try {
4263
4274
  await sleep(delayMs, options?.signal);
4264
4275
  } catch (error) {
@@ -4284,16 +4295,19 @@ var HttpClient = class {
4284
4295
  options?.signal?.addEventListener("abort", abortRequest, {
4285
4296
  once: true
4286
4297
  });
4298
+ networkPhase = "before_request";
4287
4299
  try {
4288
4300
  const requestBody = options?.formData !== void 0 ? typeof options.formData === "function" ? options.formData() : options.formData : options?.body !== void 0 ? JSON.stringify(options.body) : void 0;
4289
4301
  fetchAttempts += 1;
4290
4302
  lastRequestUrl = candidateUrl;
4303
+ networkPhase = "awaiting_headers";
4291
4304
  const response = await fetch(candidateUrl, {
4292
4305
  method,
4293
4306
  headers,
4294
4307
  body: requestBody,
4295
4308
  signal: controller.signal
4296
4309
  });
4310
+ networkPhase = "reading_body";
4297
4311
  options?.onResponse?.(response);
4298
4312
  if (response.status === 404 && options?.allowNotFound) {
4299
4313
  clearTimeout(timeoutId);
@@ -4436,7 +4450,8 @@ var HttpClient = class {
4436
4450
  failedAtUtc: new Date(failedAt).toISOString(),
4437
4451
  // Elapsed time covers the entire logical request, including retries.
4438
4452
  elapsedMs: Math.max(0, failedAt - requestStartedAt),
4439
- attempts: fetchAttempts
4453
+ attempts: fetchAttempts,
4454
+ phase: networkPhase
4440
4455
  }
4441
4456
  };
4442
4457
  if (options?.toolId) {
@@ -6335,7 +6350,7 @@ var DeeplineClient = class _DeeplineClient {
6335
6350
  purchaseCredits: (options2) => this.purchaseTargetBillingCredits(options2),
6336
6351
  recoverCreditPurchase: (options2) => this.recoverTargetBillingCreditPurchase(options2),
6337
6352
  transitionPlan: (options2) => this.transitionTargetBillingPlan(options2),
6338
- portalSession: () => this.createTargetBillingPortalSession()
6353
+ portalSession: (options2) => this.createTargetBillingPortalSession(options2)
6339
6354
  };
6340
6355
  this.workspaces = {
6341
6356
  create: (options2) => this.createWorkspace(options2)
@@ -8856,8 +8871,11 @@ var DeeplineClient = class _DeeplineClient {
8856
8871
  );
8857
8872
  }
8858
8873
  /** Create a Stripe-hosted portal session for payment recovery and invoices. */
8859
- async createTargetBillingPortalSession() {
8860
- const response = await this.http.post("/api/v2/billing/portal-sessions", {});
8874
+ async createTargetBillingPortalSession(options) {
8875
+ const response = await this.http.post(
8876
+ options?.flow === "customer_update" ? "/api/v2/billing/portal-sessions?flow=customer_update" : "/api/v2/billing/portal-sessions",
8877
+ {}
8878
+ );
8861
8879
  return response.data;
8862
8880
  }
8863
8881
  /** Create an additional workspace through the durable PAYG workflow. */
@@ -12584,7 +12602,9 @@ async function handleTargetPlanCancellation(options) {
12584
12602
  );
12585
12603
  }
12586
12604
  async function handleTargetPortal(options) {
12587
- const payload = await new DeeplineClient().billing.portalSession();
12605
+ const payload = await new DeeplineClient().billing.portalSession(
12606
+ options.billingAddress ? { flow: "customer_update" } : void 0
12607
+ );
12588
12608
  if (!options.json && !options.noOpen) openInBrowser(payload.url);
12589
12609
  printCommandEnvelope({ ok: true, ...payload }, { json: options.json });
12590
12610
  }
@@ -12871,7 +12891,7 @@ Examples:
12871
12891
  "Invoice recipient when the account has no billing email"
12872
12892
  ).option("--idempotency-key <key>", "Stable retry key").option("--json", "Emit JSON output").action(handleTargetPlan);
12873
12893
  billing.command("cancel-plan").description("Cancel a target subscription at period end, or undo it.").option("--undo", "Undo a pending period-end cancellation").option("--idempotency-key <key>", "Stable retry key").option("--json", "Emit JSON output").action(handleTargetPlanCancellation);
12874
- billing.command("portal").description("Open the Stripe-hosted billing recovery portal.").option("--no-open", "Print the URL without opening a browser").option("--json", "Emit JSON output").action(handleTargetPortal);
12894
+ billing.command("portal").description("Open the Stripe-hosted billing recovery portal.").option("--billing-address", "Open the billing address editor directly").option("--no-open", "Print the URL without opening a browser").option("--json", "Emit JSON output").action(handleTargetPortal);
12875
12895
  billing.command("plans").description("Show published plans and the plan you are on.").addHelpText(
12876
12896
  "after",
12877
12897
  `
@@ -43278,7 +43298,7 @@ function classifyNetworkFailure(error) {
43278
43298
  if (combined.includes("aborterror") || combined.includes("timeout") || combined.includes("timed out") || combined.includes("etimedout")) {
43279
43299
  return "network_timeout";
43280
43300
  }
43281
- if (combined.includes("enotfound") || combined.includes("eai_again") || combined.includes("name or service not known") || combined.includes("temporary failure in name resolution")) {
43301
+ if (combined.includes("enotfound") || combined.includes("eai_again") || combined.includes("getaddrinfo") || combined.includes("name or service not known") || combined.includes("temporary failure in name resolution")) {
43282
43302
  return "network_dns_resolution_failed";
43283
43303
  }
43284
43304
  if (combined.includes("econnrefused") || combined.includes("connection refused")) {
@@ -43301,6 +43321,14 @@ function classifyNetworkFailure(error) {
43301
43321
  return "network_error";
43302
43322
  }
43303
43323
  function classifyNetworkCauseCategory(error) {
43324
+ const seen = /* @__PURE__ */ new Set();
43325
+ let cause = error;
43326
+ while (cause && typeof cause === "object" && !seen.has(cause)) {
43327
+ seen.add(cause);
43328
+ const record3 = cause;
43329
+ if (record3.code === "UND_ERR_CONNECT_TIMEOUT") return "connect_timeout";
43330
+ cause = record3.cause;
43331
+ }
43304
43332
  switch (classifyNetworkFailure(error)) {
43305
43333
  case "network_dns_resolution_failed":
43306
43334
  return "dns";
@@ -43309,7 +43337,7 @@ function classifyNetworkCauseCategory(error) {
43309
43337
  case "network_connection_reset":
43310
43338
  return "reset";
43311
43339
  case "network_timeout":
43312
- return "connect_timeout";
43340
+ return "timeout";
43313
43341
  default:
43314
43342
  return "unknown";
43315
43343
  }
@@ -43475,8 +43503,44 @@ function resolveSdkCliFailureExitCode(error) {
43475
43503
  function resolvedFailureKind(input2) {
43476
43504
  return input2.error === void 0 ? "command_exit" : "uncaught_exception";
43477
43505
  }
43506
+ function safeRequestDiagnostics(error) {
43507
+ if (!(error instanceof DeeplineError)) return null;
43508
+ const request = error.details?.request;
43509
+ if (!request || typeof request !== "object" || Array.isArray(request))
43510
+ return null;
43511
+ const value = request;
43512
+ const result = {};
43513
+ if (typeof value.phase === "string" && [
43514
+ "before_request",
43515
+ "retry_wait",
43516
+ "awaiting_headers",
43517
+ "reading_body"
43518
+ ].includes(value.phase))
43519
+ result.phase = value.phase;
43520
+ if (typeof value.method === "string" && /^(GET|HEAD|POST|PUT|PATCH|DELETE|OPTIONS)$/.test(value.method))
43521
+ result.method = value.method;
43522
+ if (typeof value.url === "string") {
43523
+ try {
43524
+ const url = new URL(value.url);
43525
+ if (url.protocol === "https:" || url.protocol === "http:") {
43526
+ result.url = redactFailureText(`${url.origin}${url.pathname}`, 1e3);
43527
+ }
43528
+ } catch {
43529
+ }
43530
+ }
43531
+ if (typeof value.failedAtUtc === "string" && Number.isFinite(Date.parse(value.failedAtUtc))) {
43532
+ result.failedAtUtc = new Date(value.failedAtUtc).toISOString();
43533
+ }
43534
+ for (const key of ["elapsedMs", "attempts"]) {
43535
+ const number = value[key];
43536
+ if (typeof number === "number" && Number.isSafeInteger(number) && number >= 0)
43537
+ result[key] = number;
43538
+ }
43539
+ return Object.keys(result).length > 0 ? result : null;
43540
+ }
43478
43541
  function buildFailureReport(input2) {
43479
43542
  const durationMs = Math.max(0, Date.now() - input2.startedAtMs);
43543
+ const request = safeRequestDiagnostics(input2.error);
43480
43544
  const failureKind = resolvedFailureKind({
43481
43545
  exitCode: input2.exitCode,
43482
43546
  error: input2.error
@@ -43501,6 +43565,7 @@ function buildFailureReport(input2) {
43501
43565
  base_url: redactFailureText(input2.baseUrl, 400),
43502
43566
  command_summary: sanitizeCommand(input2.argv),
43503
43567
  environment: buildEnvironmentContext(),
43568
+ ...request ? { request } : {},
43504
43569
  failure_kind: failureKind,
43505
43570
  failure_code: code,
43506
43571
  failure_stage: input2.error === void 0 ? "command_exit" : "cli_main",
@@ -49591,6 +49656,7 @@ function toolContractJsonForDescribe(tool, requestedToolId) {
49591
49656
  const outputSchemaRecord = recordField2(tool, "outputSchema", "output_schema");
49592
49657
  const outputFields = toolOutputFieldsForDisplay(outputSchemaRecord);
49593
49658
  const usageGuidance = recordField2(tool, "usageGuidance", "usage_guidance");
49659
+ const guidance = recordField2(tool, "guidance");
49594
49660
  const toolExecutionResult = recordField2(
49595
49661
  usageGuidance,
49596
49662
  "toolExecutionResult",
@@ -49639,6 +49705,7 @@ function toolContractJsonForDescribe(tool, requestedToolId) {
49639
49705
  displayName: tool.displayName,
49640
49706
  cost: pricing,
49641
49707
  description: tool.description,
49708
+ ...Object.keys(guidance).length > 0 ? { guidance } : {},
49642
49709
  categories: tool.categories,
49643
49710
  ...deprecated ? {
49644
49711
  deprecated: true,
@@ -49789,6 +49856,15 @@ function printMonitorTypeContract(tool, requestedToolId) {
49789
49856
  console.log("");
49790
49857
  console.log(`More: deepline tools get ${toolId} --json`);
49791
49858
  }
49859
+ function toolGuidanceLines(guidance) {
49860
+ const record3 = isRecord9(guidance) ? guidance : {};
49861
+ const toolGuidance = stringField2(record3, "tool");
49862
+ const providerGuidance = stringField2(record3, "provider");
49863
+ return [
49864
+ ...toolGuidance ? [`- This tool: ${toolGuidance}`] : [],
49865
+ ...providerGuidance ? [`- Provider: ${providerGuidance}`] : []
49866
+ ];
49867
+ }
49792
49868
  function printCompactToolContract(tool, requestedToolId) {
49793
49869
  if (isMonitorTypeTool(tool)) {
49794
49870
  printMonitorTypeContract(tool, requestedToolId);
@@ -49810,6 +49886,10 @@ function printCompactToolContract(tool, requestedToolId) {
49810
49886
  if (Array.isArray(contract.categories) && contract.categories.length) {
49811
49887
  console.log(`Tags: ${contract.categories.join(", ")}`);
49812
49888
  }
49889
+ const guidanceLines = toolGuidanceLines(contract.guidance);
49890
+ if (guidanceLines.length > 0) {
49891
+ console.log(["Guidance:", ...guidanceLines].join("\n"));
49892
+ }
49813
49893
  printToolOutputArrayShape(contract);
49814
49894
  printToolExecutionHints(contract);
49815
49895
  if (contract.deprecated === true) {
@@ -50877,6 +50957,7 @@ export default definePlay(${JSON.stringify(playName)}, async (ctx) => {
50877
50957
  }
50878
50958
  function buildToolExecuteBaseEnvelope(input2) {
50879
50959
  const envelope = commandEnvelopeFromRawResponse(input2.rawResponse);
50960
+ const guidanceLines = toolExecuteExitCode(envelope) !== 0 || input2.listExpected === true && !input2.listConversion ? toolGuidanceLines(input2.guidance) : [];
50880
50961
  const warningMessages = extractToolExecutionWarningMessages(
50881
50962
  input2.rawResponse
50882
50963
  );
@@ -50928,6 +51009,7 @@ function buildToolExecuteBaseEnvelope(input2) {
50928
51009
  inspect: inspectCommand,
50929
51010
  ...billingLookup ? { billing: billingLookup } : {},
50930
51011
  ...apifyRecovery ?? {},
51012
+ ...guidanceLines.length > 0 ? { guidance: input2.guidance } : {},
50931
51013
  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.",
50932
51014
  ...input2.listConversion ? {
50933
51015
  expandToPlay: "Use stable map and step keys so reruns are idempotent: completed rows are reused, and only missing or stale work runs again.",
@@ -50955,7 +51037,8 @@ function buildToolExecuteBaseEnvelope(input2) {
50955
51037
  ] : summaryEntries.length > 0 ? summaryEntries.map(
50956
51038
  ([key, value]) => `${key}=${String(value)}`
50957
51039
  ) : [JSON.stringify(input2.rawResponse, null, 2)]
50958
- }
51040
+ },
51041
+ ...guidanceLines.length > 0 ? [{ title: "guidance", lines: guidanceLines }] : []
50959
51042
  ],
50960
51043
  actions
50961
51044
  }
@@ -51127,10 +51210,17 @@ async function executeTool(args) {
51127
51210
  ...idempotencyKey ? { idempotencyKey } : {},
51128
51211
  ...parsed.recoveryTimeoutMs !== void 0 ? { recoveryTimeoutMs: parsed.recoveryTimeoutMs } : {},
51129
51212
  searchRef: recentSearchRef()
51213
+ }).catch((error) => {
51214
+ const guidanceLines = toolGuidanceLines(metadata.guidance);
51215
+ if (guidanceLines.length > 0) {
51216
+ console.error(
51217
+ [`Guidance for ${parsed.toolId}:`, ...guidanceLines].join("\n")
51218
+ );
51219
+ }
51220
+ throw error;
51130
51221
  });
51131
- const listConversion = tryConvertToList(rawResponse, {
51132
- listExtractorPaths: listExtractorPathsFromUsageGuidance(metadata)
51133
- });
51222
+ const listExtractorPaths = listExtractorPathsFromUsageGuidance(metadata);
51223
+ const listConversion = tryConvertToList(rawResponse, { listExtractorPaths });
51134
51224
  const summary = extractSummaryFields(rawResponse);
51135
51225
  const baseEnvelope = buildToolExecuteBaseEnvelope({
51136
51226
  toolId: parsed.toolId,
@@ -51138,7 +51228,9 @@ async function executeTool(args) {
51138
51228
  ...idempotencyKey ? { idempotencyKey } : {},
51139
51229
  rawResponse,
51140
51230
  listConversion,
51141
- summary
51231
+ summary,
51232
+ guidance: metadata.guidance,
51233
+ listExpected: listExtractorPaths.length > 0
51142
51234
  });
51143
51235
  const executeExitCode = toolExecuteExitCode(baseEnvelope);
51144
51236
  const delivered = (() => {
package/dist/index.d.mts CHANGED
@@ -1269,6 +1269,11 @@ interface ToolDefinition extends ToolExecutionMetadataFields {
1269
1269
  outputSchema?: Record<string, unknown>;
1270
1270
  /** User-facing pricing summary. Internal provider/settlement costs are intentionally omitted. */
1271
1271
  pricing?: ToolPricingSummary | null;
1272
+ /** How to use the tool well: the provider's summary and the tool's own notes. */
1273
+ guidance?: {
1274
+ provider?: string;
1275
+ tool?: string;
1276
+ };
1272
1277
  /** Copyable play-runtime guidance for V2 tool execution results. */
1273
1278
  usageGuidance?: {
1274
1279
  execute?: string;
@@ -4533,6 +4538,15 @@ type TargetBillingStatusResult = {
4533
4538
  payment_state: string;
4534
4539
  recharge_state: string;
4535
4540
  billing_email?: string | null;
4541
+ /** Omitted when unavailable; null when no address has been saved. */
4542
+ billing_address?: {
4543
+ line1: string | null;
4544
+ line2: string | null;
4545
+ city: string | null;
4546
+ state: string | null;
4547
+ postal_code: string | null;
4548
+ country: string | null;
4549
+ } | null;
4536
4550
  collection_method?: 'charge_automatically' | 'send_invoice';
4537
4551
  payment_access_policy?: 'payment_required' | 'net_30' | 'net_60';
4538
4552
  plan_invoice?: {
@@ -4863,7 +4877,9 @@ type BillingNamespace = {
4863
4877
  /** Start, change, cancel, or undo a target plan transition. */
4864
4878
  transitionPlan: (options: TargetBillingPlanTransitionOptions) => Promise<TargetBillingMutationResult>;
4865
4879
  /** Create a Stripe-hosted billing Portal session. */
4866
- portalSession: () => Promise<{
4880
+ portalSession: (options?: {
4881
+ flow?: 'customer_update';
4882
+ }) => Promise<{
4867
4883
  url: string;
4868
4884
  }>;
4869
4885
  };
@@ -6022,7 +6038,9 @@ declare class DeeplineClient {
6022
6038
  */
6023
6039
  transitionTargetBillingPlan(options: TargetBillingPlanTransitionOptions): Promise<TargetBillingMutationResult>;
6024
6040
  /** Create a Stripe-hosted portal session for payment recovery and invoices. */
6025
- createTargetBillingPortalSession(): Promise<{
6041
+ createTargetBillingPortalSession(options?: {
6042
+ flow?: 'customer_update';
6043
+ }): Promise<{
6026
6044
  url: string;
6027
6045
  }>;
6028
6046
  /** Create an additional workspace through the durable PAYG workflow. */
package/dist/index.d.ts CHANGED
@@ -1269,6 +1269,11 @@ interface ToolDefinition extends ToolExecutionMetadataFields {
1269
1269
  outputSchema?: Record<string, unknown>;
1270
1270
  /** User-facing pricing summary. Internal provider/settlement costs are intentionally omitted. */
1271
1271
  pricing?: ToolPricingSummary | null;
1272
+ /** How to use the tool well: the provider's summary and the tool's own notes. */
1273
+ guidance?: {
1274
+ provider?: string;
1275
+ tool?: string;
1276
+ };
1272
1277
  /** Copyable play-runtime guidance for V2 tool execution results. */
1273
1278
  usageGuidance?: {
1274
1279
  execute?: string;
@@ -4533,6 +4538,15 @@ type TargetBillingStatusResult = {
4533
4538
  payment_state: string;
4534
4539
  recharge_state: string;
4535
4540
  billing_email?: string | null;
4541
+ /** Omitted when unavailable; null when no address has been saved. */
4542
+ billing_address?: {
4543
+ line1: string | null;
4544
+ line2: string | null;
4545
+ city: string | null;
4546
+ state: string | null;
4547
+ postal_code: string | null;
4548
+ country: string | null;
4549
+ } | null;
4536
4550
  collection_method?: 'charge_automatically' | 'send_invoice';
4537
4551
  payment_access_policy?: 'payment_required' | 'net_30' | 'net_60';
4538
4552
  plan_invoice?: {
@@ -4863,7 +4877,9 @@ type BillingNamespace = {
4863
4877
  /** Start, change, cancel, or undo a target plan transition. */
4864
4878
  transitionPlan: (options: TargetBillingPlanTransitionOptions) => Promise<TargetBillingMutationResult>;
4865
4879
  /** Create a Stripe-hosted billing Portal session. */
4866
- portalSession: () => Promise<{
4880
+ portalSession: (options?: {
4881
+ flow?: 'customer_update';
4882
+ }) => Promise<{
4867
4883
  url: string;
4868
4884
  }>;
4869
4885
  };
@@ -6022,7 +6038,9 @@ declare class DeeplineClient {
6022
6038
  */
6023
6039
  transitionTargetBillingPlan(options: TargetBillingPlanTransitionOptions): Promise<TargetBillingMutationResult>;
6024
6040
  /** Create a Stripe-hosted portal session for payment recovery and invoices. */
6025
- createTargetBillingPortalSession(): Promise<{
6041
+ createTargetBillingPortalSession(options?: {
6042
+ flow?: 'customer_update';
6043
+ }): Promise<{
6026
6044
  url: string;
6027
6045
  }>;
6028
6046
  /** Create an additional workspace through the durable PAYG workflow. */
package/dist/index.js CHANGED
@@ -814,6 +814,12 @@ function resolveConfig(options) {
814
814
  };
815
815
  }
816
816
 
817
+ // ../integration-contracts/opensosdata/execution-policy.ts
818
+ var OPENSOSDATA_LOOKUP_REQUEST_TIMEOUT_MS = 12e4;
819
+ var OPENSOSDATA_POLL_INTERVAL_MS = 3e3;
820
+ var OPENSOSDATA_POLL_TIMEOUT_MS = 9e4;
821
+ var OPENSOSDATA_LOOKUP_CLIENT_TIMEOUT_MS = 6e4 + OPENSOSDATA_LOOKUP_REQUEST_TIMEOUT_MS + OPENSOSDATA_POLL_TIMEOUT_MS + OPENSOSDATA_POLL_INTERVAL_MS + OPENSOSDATA_LOOKUP_REQUEST_TIMEOUT_MS + 15e3;
822
+
817
823
  // ../integration-contracts/theirstack/execution-policy.ts
818
824
  var THEIRSTACK_SLOW_JOB_SEARCH_PROVIDER_TIMEOUT_MS = 135e3;
819
825
  var THEIRSTACK_SLOW_JOB_SEARCH_CLIENT_TIMEOUT_MS = 6e4 + THEIRSTACK_SLOW_JOB_SEARCH_PROVIDER_TIMEOUT_MS + 15e3;
@@ -964,6 +970,9 @@ var APIFY_SYNC_DEFAULT_TIMEOUT_MS = 3e5;
964
970
  var APIFY_SYNC_RESPONSE_GRACE_MS = 9e4;
965
971
  function resolveToolExecuteTimeoutMs(toolId, input) {
966
972
  const normalized = toolId.trim().toLowerCase();
973
+ if (normalized === "opensosdata_business_lookup") {
974
+ return OPENSOSDATA_LOOKUP_CLIENT_TIMEOUT_MS;
975
+ }
967
976
  if (normalized === "apify_run_actor_sync") {
968
977
  const requestedTimeoutMs = input.timeoutMs ?? APIFY_SYNC_DEFAULT_TIMEOUT_MS;
969
978
  if (typeof requestedTimeoutMs === "number" && Number.isFinite(requestedTimeoutMs) && requestedTimeoutMs > 0) {
@@ -1267,7 +1276,7 @@ var SDK_RELEASE = {
1267
1276
  // getters keep their established compatibility behavior.
1268
1277
  // 0.3.1 deprecated the legacy `deepline enrich` command in favor of Plays.
1269
1278
  // 0.3.90 is the first deliberately versioned SDK release for API v3.
1270
- version: "0.3.239",
1279
+ version: "0.3.240",
1271
1280
  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.",
1272
1281
  packageCapabilities: {
1273
1282
  updatePreferences: 1
@@ -2022,6 +2031,7 @@ var HttpClient = class {
2022
2031
  let fetchAttempts = 0;
2023
2032
  let lastRequestUrl = url;
2024
2033
  let networkFailedAt;
2034
+ let networkPhase = "before_request";
2025
2035
  const headers = this.authHeaders(options?.headers);
2026
2036
  if (options?.body !== void 0) {
2027
2037
  headers["Content-Type"] = "application/json";
@@ -2040,6 +2050,7 @@ var HttpClient = class {
2040
2050
  const backoffMs = Math.min(1e3 * Math.pow(2, attempt - 1), 3e4);
2041
2051
  const delayMs = retryAfterDelayMs === null ? backoffMs : Math.max(backoffMs, retryAfterDelayMs);
2042
2052
  retryAfterDelayMs = null;
2053
+ networkPhase = "retry_wait";
2043
2054
  try {
2044
2055
  await sleep(delayMs, options?.signal);
2045
2056
  } catch (error) {
@@ -2065,16 +2076,19 @@ var HttpClient = class {
2065
2076
  options?.signal?.addEventListener("abort", abortRequest, {
2066
2077
  once: true
2067
2078
  });
2079
+ networkPhase = "before_request";
2068
2080
  try {
2069
2081
  const requestBody = options?.formData !== void 0 ? typeof options.formData === "function" ? options.formData() : options.formData : options?.body !== void 0 ? JSON.stringify(options.body) : void 0;
2070
2082
  fetchAttempts += 1;
2071
2083
  lastRequestUrl = candidateUrl;
2084
+ networkPhase = "awaiting_headers";
2072
2085
  const response = await fetch(candidateUrl, {
2073
2086
  method,
2074
2087
  headers,
2075
2088
  body: requestBody,
2076
2089
  signal: controller.signal
2077
2090
  });
2091
+ networkPhase = "reading_body";
2078
2092
  options?.onResponse?.(response);
2079
2093
  if (response.status === 404 && options?.allowNotFound) {
2080
2094
  clearTimeout(timeoutId);
@@ -2217,7 +2231,8 @@ var HttpClient = class {
2217
2231
  failedAtUtc: new Date(failedAt).toISOString(),
2218
2232
  // Elapsed time covers the entire logical request, including retries.
2219
2233
  elapsedMs: Math.max(0, failedAt - requestStartedAt),
2220
- attempts: fetchAttempts
2234
+ attempts: fetchAttempts,
2235
+ phase: networkPhase
2221
2236
  }
2222
2237
  };
2223
2238
  if (options?.toolId) {
@@ -3992,7 +4007,7 @@ var DeeplineClient = class _DeeplineClient {
3992
4007
  purchaseCredits: (options2) => this.purchaseTargetBillingCredits(options2),
3993
4008
  recoverCreditPurchase: (options2) => this.recoverTargetBillingCreditPurchase(options2),
3994
4009
  transitionPlan: (options2) => this.transitionTargetBillingPlan(options2),
3995
- portalSession: () => this.createTargetBillingPortalSession()
4010
+ portalSession: (options2) => this.createTargetBillingPortalSession(options2)
3996
4011
  };
3997
4012
  this.workspaces = {
3998
4013
  create: (options2) => this.createWorkspace(options2)
@@ -6513,8 +6528,11 @@ var DeeplineClient = class _DeeplineClient {
6513
6528
  );
6514
6529
  }
6515
6530
  /** Create a Stripe-hosted portal session for payment recovery and invoices. */
6516
- async createTargetBillingPortalSession() {
6517
- const response = await this.http.post("/api/v2/billing/portal-sessions", {});
6531
+ async createTargetBillingPortalSession(options) {
6532
+ const response = await this.http.post(
6533
+ options?.flow === "customer_update" ? "/api/v2/billing/portal-sessions?flow=customer_update" : "/api/v2/billing/portal-sessions",
6534
+ {}
6535
+ );
6518
6536
  return response.data;
6519
6537
  }
6520
6538
  /** Create an additional workspace through the durable PAYG workflow. */
package/dist/index.mjs CHANGED
@@ -718,6 +718,12 @@ function resolveConfig(options) {
718
718
  };
719
719
  }
720
720
 
721
+ // ../integration-contracts/opensosdata/execution-policy.ts
722
+ var OPENSOSDATA_LOOKUP_REQUEST_TIMEOUT_MS = 12e4;
723
+ var OPENSOSDATA_POLL_INTERVAL_MS = 3e3;
724
+ var OPENSOSDATA_POLL_TIMEOUT_MS = 9e4;
725
+ var OPENSOSDATA_LOOKUP_CLIENT_TIMEOUT_MS = 6e4 + OPENSOSDATA_LOOKUP_REQUEST_TIMEOUT_MS + OPENSOSDATA_POLL_TIMEOUT_MS + OPENSOSDATA_POLL_INTERVAL_MS + OPENSOSDATA_LOOKUP_REQUEST_TIMEOUT_MS + 15e3;
726
+
721
727
  // ../integration-contracts/theirstack/execution-policy.ts
722
728
  var THEIRSTACK_SLOW_JOB_SEARCH_PROVIDER_TIMEOUT_MS = 135e3;
723
729
  var THEIRSTACK_SLOW_JOB_SEARCH_CLIENT_TIMEOUT_MS = 6e4 + THEIRSTACK_SLOW_JOB_SEARCH_PROVIDER_TIMEOUT_MS + 15e3;
@@ -868,6 +874,9 @@ var APIFY_SYNC_DEFAULT_TIMEOUT_MS = 3e5;
868
874
  var APIFY_SYNC_RESPONSE_GRACE_MS = 9e4;
869
875
  function resolveToolExecuteTimeoutMs(toolId, input) {
870
876
  const normalized = toolId.trim().toLowerCase();
877
+ if (normalized === "opensosdata_business_lookup") {
878
+ return OPENSOSDATA_LOOKUP_CLIENT_TIMEOUT_MS;
879
+ }
871
880
  if (normalized === "apify_run_actor_sync") {
872
881
  const requestedTimeoutMs = input.timeoutMs ?? APIFY_SYNC_DEFAULT_TIMEOUT_MS;
873
882
  if (typeof requestedTimeoutMs === "number" && Number.isFinite(requestedTimeoutMs) && requestedTimeoutMs > 0) {
@@ -1171,7 +1180,7 @@ var SDK_RELEASE = {
1171
1180
  // getters keep their established compatibility behavior.
1172
1181
  // 0.3.1 deprecated the legacy `deepline enrich` command in favor of Plays.
1173
1182
  // 0.3.90 is the first deliberately versioned SDK release for API v3.
1174
- version: "0.3.239",
1183
+ version: "0.3.240",
1175
1184
  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.",
1176
1185
  packageCapabilities: {
1177
1186
  updatePreferences: 1
@@ -1926,6 +1935,7 @@ var HttpClient = class {
1926
1935
  let fetchAttempts = 0;
1927
1936
  let lastRequestUrl = url;
1928
1937
  let networkFailedAt;
1938
+ let networkPhase = "before_request";
1929
1939
  const headers = this.authHeaders(options?.headers);
1930
1940
  if (options?.body !== void 0) {
1931
1941
  headers["Content-Type"] = "application/json";
@@ -1944,6 +1954,7 @@ var HttpClient = class {
1944
1954
  const backoffMs = Math.min(1e3 * Math.pow(2, attempt - 1), 3e4);
1945
1955
  const delayMs = retryAfterDelayMs === null ? backoffMs : Math.max(backoffMs, retryAfterDelayMs);
1946
1956
  retryAfterDelayMs = null;
1957
+ networkPhase = "retry_wait";
1947
1958
  try {
1948
1959
  await sleep(delayMs, options?.signal);
1949
1960
  } catch (error) {
@@ -1969,16 +1980,19 @@ var HttpClient = class {
1969
1980
  options?.signal?.addEventListener("abort", abortRequest, {
1970
1981
  once: true
1971
1982
  });
1983
+ networkPhase = "before_request";
1972
1984
  try {
1973
1985
  const requestBody = options?.formData !== void 0 ? typeof options.formData === "function" ? options.formData() : options.formData : options?.body !== void 0 ? JSON.stringify(options.body) : void 0;
1974
1986
  fetchAttempts += 1;
1975
1987
  lastRequestUrl = candidateUrl;
1988
+ networkPhase = "awaiting_headers";
1976
1989
  const response = await fetch(candidateUrl, {
1977
1990
  method,
1978
1991
  headers,
1979
1992
  body: requestBody,
1980
1993
  signal: controller.signal
1981
1994
  });
1995
+ networkPhase = "reading_body";
1982
1996
  options?.onResponse?.(response);
1983
1997
  if (response.status === 404 && options?.allowNotFound) {
1984
1998
  clearTimeout(timeoutId);
@@ -2121,7 +2135,8 @@ var HttpClient = class {
2121
2135
  failedAtUtc: new Date(failedAt).toISOString(),
2122
2136
  // Elapsed time covers the entire logical request, including retries.
2123
2137
  elapsedMs: Math.max(0, failedAt - requestStartedAt),
2124
- attempts: fetchAttempts
2138
+ attempts: fetchAttempts,
2139
+ phase: networkPhase
2125
2140
  }
2126
2141
  };
2127
2142
  if (options?.toolId) {
@@ -3896,7 +3911,7 @@ var DeeplineClient = class _DeeplineClient {
3896
3911
  purchaseCredits: (options2) => this.purchaseTargetBillingCredits(options2),
3897
3912
  recoverCreditPurchase: (options2) => this.recoverTargetBillingCreditPurchase(options2),
3898
3913
  transitionPlan: (options2) => this.transitionTargetBillingPlan(options2),
3899
- portalSession: () => this.createTargetBillingPortalSession()
3914
+ portalSession: (options2) => this.createTargetBillingPortalSession(options2)
3900
3915
  };
3901
3916
  this.workspaces = {
3902
3917
  create: (options2) => this.createWorkspace(options2)
@@ -6417,8 +6432,11 @@ var DeeplineClient = class _DeeplineClient {
6417
6432
  );
6418
6433
  }
6419
6434
  /** Create a Stripe-hosted portal session for payment recovery and invoices. */
6420
- async createTargetBillingPortalSession() {
6421
- const response = await this.http.post("/api/v2/billing/portal-sessions", {});
6435
+ async createTargetBillingPortalSession(options) {
6436
+ const response = await this.http.post(
6437
+ options?.flow === "customer_update" ? "/api/v2/billing/portal-sessions?flow=customer_update" : "/api/v2/billing/portal-sessions",
6438
+ {}
6439
+ );
6422
6440
  return response.data;
6423
6441
  }
6424
6442
  /** Create an additional workspace through the durable PAYG workflow. */
@@ -33,6 +33,7 @@
33
33
  "dist/bundling-sources/shared_libs/integration-contracts/index.ts",
34
34
  "dist/bundling-sources/shared_libs/integration-contracts/monitor-fleet-contract.ts",
35
35
  "dist/bundling-sources/shared_libs/integration-contracts/monitor-input-contract.ts",
36
+ "dist/bundling-sources/shared_libs/integration-contracts/opensosdata/execution-policy.ts",
36
37
  "dist/bundling-sources/shared_libs/integration-contracts/README.md",
37
38
  "dist/bundling-sources/shared_libs/integration-contracts/theirstack/execution-policy.ts",
38
39
  "dist/bundling-sources/shared_libs/integration-contracts/waterfall/execution-policy.ts",
@@ -149,7 +149,7 @@ type SdkRelease = {
149
149
  supportPolicy: SdkSupportPolicy;
150
150
  };
151
151
  declare const SDK_RELEASE: {
152
- readonly version: "0.3.239";
152
+ readonly version: "0.3.240";
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.239";
152
+ readonly version: "0.3.240";
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.239",
77
+ version: "0.3.240",
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.239",
51
+ version: "0.3.240",
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.239",
3
+ "version": "0.3.240",
4
4
  "description": "GTM data CLI and TypeScript SDK for coding agents",
5
5
  "license": "MIT",
6
6
  "homepage": "https://code.deepline.com",