deepline 0.3.140 → 0.3.142

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 (26) hide show
  1. package/dist/bundling-sources/sdk/src/client.ts +18 -0
  2. package/dist/bundling-sources/sdk/src/release.ts +1 -1
  3. package/dist/bundling-sources/sdk/src/types.ts +65 -2
  4. package/dist/bundling-sources/shared_libs/observability/dlq.ts +11 -0
  5. package/dist/bundling-sources/shared_libs/observability/queue-health.ts +111 -0
  6. package/dist/bundling-sources/shared_libs/play-runtime/bettercontact-batching.ts +34 -8
  7. package/dist/bundling-sources/shared_libs/play-runtime/context.ts +271 -44
  8. package/dist/bundling-sources/shared_libs/play-runtime/ctx-types.ts +25 -6
  9. package/dist/bundling-sources/shared_libs/play-runtime/governor/app-runtime-rate-state-backend.ts +132 -8
  10. package/dist/bundling-sources/shared_libs/play-runtime/play-runtime-batching-registry.ts +3 -1
  11. package/dist/bundling-sources/shared_libs/play-runtime/runner-app/index.ts +49 -54
  12. package/dist/bundling-sources/shared_libs/play-runtime/runtime-api.ts +14 -7
  13. package/dist/bundling-sources/shared_libs/play-runtime/scheduler-backends/postgres-rate-state.ts +118 -29
  14. package/dist/bundling-sources/shared_libs/play-runtime/scheduler-backends/runtime-queue-health.ts +183 -36
  15. package/dist/bundling-sources/shared_libs/product-notifications/events.ts +4 -1
  16. package/dist/cli/index.js +247 -12
  17. package/dist/cli/index.mjs +247 -12
  18. package/dist/index.d.mts +69 -2
  19. package/dist/index.d.ts +69 -2
  20. package/dist/index.js +2 -1
  21. package/dist/index.mjs +2 -1
  22. package/dist/release.d.mts +1 -1
  23. package/dist/release.d.ts +1 -1
  24. package/dist/release.js +1 -1
  25. package/dist/release.mjs +1 -1
  26. package/package.json +1 -1
@@ -3063,7 +3063,7 @@ var SDK_RELEASE = {
3063
3063
  // getters keep their established compatibility behavior.
3064
3064
  // 0.3.1 deprecated the legacy `deepline enrich` command in favor of Plays.
3065
3065
  // 0.3.90 is the first deliberately versioned SDK release for API v3.
3066
- version: "0.3.140",
3066
+ version: "0.3.142",
3067
3067
  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.",
3068
3068
  packageCapabilities: {
3069
3069
  updatePreferences: 1
@@ -9625,6 +9625,7 @@ var DeeplineClient = class _DeeplineClient {
9625
9625
  "/api/v2/billing/plan-transitions",
9626
9626
  {
9627
9627
  action: options.action,
9628
+ ...options.action === "start_or_change" && options.billingEmail ? { billing_email: options.billingEmail } : {},
9628
9629
  ...options.targetPlanSku ? { target_plan_sku: options.targetPlanSku } : {}
9629
9630
  },
9630
9631
  { "Idempotency-Key": idempotencyKey },
@@ -11097,6 +11098,10 @@ function errorToJsonPayload(error) {
11097
11098
  if (maybeRecord?.details && typeof maybeRecord.details === "object" && !Array.isArray(maybeRecord.details)) {
11098
11099
  details.details = maybeRecord.details;
11099
11100
  }
11101
+ const providerConcurrency = providerConcurrencyDiagnostic(maybeRecord);
11102
+ if (providerConcurrency) {
11103
+ details.providerConcurrency = providerConcurrency;
11104
+ }
11100
11105
  if (typeof maybeRecord?.cause === "string") {
11101
11106
  details.cause = maybeRecord.cause;
11102
11107
  }
@@ -11110,6 +11115,33 @@ function errorToJsonPayload(error) {
11110
11115
  }
11111
11116
  };
11112
11117
  }
11118
+ function formatProviderConcurrencyDiagnostic(error) {
11119
+ const value = error && typeof error === "object" ? error : null;
11120
+ const diagnostic = providerConcurrencyDiagnostic(value);
11121
+ if (!diagnostic) return null;
11122
+ const count = diagnostic.inFlightProviderRequestsAt429;
11123
+ const concurrency = count > 1 ? `${count - 1} other same-provider request${count === 2 ? "" : "s"} overlapped the failed request` : "no other same-provider request was active";
11124
+ return `Provider concurrency at the 429: ${count} active request${count === 1 ? "" : "s"} in this Play execution, including the failed request; ${concurrency}. Other Play executions and direct CLI/API calls are not included.`;
11125
+ }
11126
+ function providerConcurrencyDiagnostic(value) {
11127
+ if (!value || value.origin !== "provider" || value.statusCode !== 429 && value.status !== 429) {
11128
+ return null;
11129
+ }
11130
+ const publicDetails = value.publicDetails;
11131
+ if (!publicDetails || typeof publicDetails !== "object" || Array.isArray(publicDetails)) {
11132
+ return null;
11133
+ }
11134
+ const details = publicDetails;
11135
+ const count = details.inFlightProviderRequestsAt429;
11136
+ if (details.providerConcurrencyScope !== "same_provider_in_play_execution" || details.includesFailedRequest !== true || typeof count !== "number" || !Number.isInteger(count) || count < 1) {
11137
+ return null;
11138
+ }
11139
+ return {
11140
+ scope: "same_provider_in_play_execution",
11141
+ inFlightProviderRequestsAt429: count,
11142
+ includesFailedRequest: true
11143
+ };
11144
+ }
11113
11145
  function printJsonError(error) {
11114
11146
  printJson(errorToJsonPayload(error));
11115
11147
  }
@@ -13148,6 +13180,7 @@ async function handleTargetPlan(planSku, options) {
13148
13180
  const payload = await new DeeplineClient().billing.transitionPlan({
13149
13181
  action: "start_or_change",
13150
13182
  targetPlanSku: planSku,
13183
+ ...options.billingEmail ? { billingEmail: options.billingEmail } : {},
13151
13184
  idempotencyKey
13152
13185
  });
13153
13186
  printCommandEnvelope(
@@ -13432,6 +13465,9 @@ Examples:
13432
13465
  billing.command("change-plan").description("Start or change the target billing plan.").argument(
13433
13466
  "<plan_sku>",
13434
13467
  "payg-v1, builder-v1, growth-v1, growth-canary-v1, or team-v1"
13468
+ ).option(
13469
+ "--billing-email <email>",
13470
+ "Invoice recipient when the account has no billing email"
13435
13471
  ).option("--idempotency-key <key>", "Stable retry key").option("--json", "Emit JSON output").action(handleTargetPlan);
13436
13472
  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);
13437
13473
  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);
@@ -25449,6 +25485,14 @@ function buildRunPackageTextLines(packaged) {
25449
25485
  const lines = isRuntimeLimitCheckpoint ? runtimeLimitCheckpointLines(packaged, runId, checkpointFailure) : [
25450
25486
  `${status === "completed" ? "\u2713" : status === "failed" ? "\u2717" : "\u2022"} ${status} ${runId}`
25451
25487
  ];
25488
+ const outcome = typeof run.outcome === "string" ? run.outcome : null;
25489
+ if (outcome) lines.push(` outcome: ${outcome}`);
25490
+ const recovery = readRecord(run.recovery);
25491
+ if (recovery) {
25492
+ const mode = typeof recovery.mode === "string" ? recovery.mode : "recovered";
25493
+ const sourceRunId = typeof recovery.sourceRunId === "string" ? ` from ${recovery.sourceRunId}` : "";
25494
+ lines.push(` recovery: ${mode}${sourceRunId}`);
25495
+ }
25452
25496
  const runError = typeof run.error === "string" && run.error.trim() ? run.error.trim() : null;
25453
25497
  const structuredRuntimeLimitMessage = typeof runtimeLimitFailure?.message === "string" && runtimeLimitFailure.message.trim() ? `${typeof runtimeLimitFailure.code === "string" ? runtimeLimitFailure.code : "RUNTIME_LIMIT_EXCEEDED"}: ${runtimeLimitFailure.message.trim()}` : null;
25454
25498
  const displayRunError = structuredRuntimeLimitMessage ?? runError;
@@ -48231,6 +48275,8 @@ function toolContractJsonForDescribe(tool, requestedToolId) {
48231
48275
  const inputSchema = publicToolInputSchemaForDescribe(
48232
48276
  recordField2(tool, "inputSchema", "input_schema")
48233
48277
  );
48278
+ const outputSchemaRecord = recordField2(tool, "outputSchema", "output_schema");
48279
+ const outputFields = toolOutputFieldsForDisplay(outputSchemaRecord);
48234
48280
  const usageGuidance = recordField2(tool, "usageGuidance", "usage_guidance");
48235
48281
  const toolExecutionResult = recordField2(
48236
48282
  usageGuidance,
@@ -48244,6 +48290,18 @@ function toolContractJsonForDescribe(tool, requestedToolId) {
48244
48290
  arrayField2(toolExecutionResult, "extractedValues", "extracted_values")
48245
48291
  );
48246
48292
  const pricing = Capability.fromCatalogEntry(tool).describe().customerCost();
48293
+ const executionMetadataRecord = recordField2(
48294
+ tool,
48295
+ "executionMetadata",
48296
+ "execution_metadata"
48297
+ );
48298
+ const executionMetadata = Object.keys(executionMetadataRecord).length > 0 ? executionMetadataRecord : null;
48299
+ const batchCapabilityRecord = recordField2(
48300
+ tool,
48301
+ "batchCapability",
48302
+ "batch_capability"
48303
+ );
48304
+ const batchCapability = Object.keys(batchCapabilityRecord).length > 0 ? batchCapabilityRecord : null;
48247
48305
  const deprecation = recordField2(tool, "deprecation");
48248
48306
  const replacementToolId = stringField2(
48249
48307
  deprecation,
@@ -48277,14 +48335,14 @@ function toolContractJsonForDescribe(tool, requestedToolId) {
48277
48335
  ...deprecationExecution ? { execution: deprecationExecution } : {}
48278
48336
  }
48279
48337
  } : {},
48280
- inputFields: inputFields.map((field) => ({
48281
- name: field.name,
48282
- type: field.type ?? "unknown",
48283
- required: Boolean(field.required),
48284
- ...field.description ? { description: field.description } : {},
48285
- ...Object.prototype.hasOwnProperty.call(field, "default") ? { default: field.default } : {}
48286
- })),
48338
+ inputFields: inputFields.map(inputFieldJsonForDescribe),
48287
48339
  inputSchema,
48340
+ ...Object.keys(outputSchemaRecord).length > 0 ? {
48341
+ outputSchema: publicToolInputSchemaForDescribe(outputSchemaRecord),
48342
+ outputFields: outputFields.map(inputFieldJsonForDescribe)
48343
+ } : {},
48344
+ ...executionMetadata ? { executionMetadata } : {},
48345
+ ...batchCapability ? { batchCapability } : {},
48288
48346
  cost: pricing,
48289
48347
  getters: {
48290
48348
  extractedLists,
@@ -48436,6 +48494,8 @@ function printCompactToolContract(tool, requestedToolId) {
48436
48494
  if (Array.isArray(contract.categories) && contract.categories.length) {
48437
48495
  console.log(`Tags: ${contract.categories.join(", ")}`);
48438
48496
  }
48497
+ printToolOutputArrayShape(contract);
48498
+ printToolExecutionHints(contract);
48439
48499
  if (contract.deprecated === true) {
48440
48500
  const deprecation = isRecord12(contract.deprecation) ? contract.deprecation : {};
48441
48501
  const message = stringField2(deprecation, "message");
@@ -48472,12 +48532,13 @@ function printCompactToolContract(tool, requestedToolId) {
48472
48532
  const description = stringField2(field, "description");
48473
48533
  const enumValues = Array.isArray(field.enum) ? field.enum : [];
48474
48534
  const enumSuffix = enumValues.length ? ` enum=${enumValues.map(String).join("|")}` : "";
48535
+ const itemBoundsSuffix = arrayItemBoundsSuffix(field);
48475
48536
  const defaultSuffix = Object.prototype.hasOwnProperty.call(
48476
48537
  field,
48477
48538
  "default"
48478
48539
  ) ? ` default=${JSON.stringify(field.default)}` : "";
48479
48540
  console.log(
48480
- `- ${name}${required}: ${type}${enumSuffix}${defaultSuffix}${description ? ` - ${description}` : ""}`
48541
+ `- ${name}${required}: ${type}${enumSuffix}${itemBoundsSuffix}${defaultSuffix}${description ? ` - ${description}` : ""}`
48481
48542
  );
48482
48543
  }
48483
48544
  }
@@ -48557,15 +48618,17 @@ function printToolSchemaOnly(tool, requestedToolId) {
48557
48618
  const description = typeof field.description === "string" ? field.description : "";
48558
48619
  const enumValues = Array.isArray(field.enum) ? field.enum : [];
48559
48620
  const enumSuffix = enumValues.length ? ` enum=${enumValues.map(String).join("|")}` : "";
48621
+ const itemBoundsSuffix = arrayItemBoundsSuffix(field);
48560
48622
  const defaultSuffix = Object.prototype.hasOwnProperty.call(
48561
48623
  field,
48562
48624
  "default"
48563
48625
  ) ? ` default=${JSON.stringify(field.default)}` : "";
48564
48626
  console.log(
48565
- `- ${name}${required}: ${type}${enumSuffix}${defaultSuffix}${description ? ` - ${description}` : ""}`
48627
+ `- ${name}${required}: ${type}${enumSuffix}${itemBoundsSuffix}${defaultSuffix}${description ? ` - ${description}` : ""}`
48566
48628
  );
48567
48629
  }
48568
48630
  }
48631
+ printToolOutputArrayShape(contract);
48569
48632
  const declaredSchema = declaredToolJsonSchema(
48570
48633
  recordField2(contract, "inputSchema")
48571
48634
  );
@@ -48741,11 +48804,19 @@ function toolMetadataJsonForDescribe(tool, requestedToolId) {
48741
48804
  deepline_pricing_details: _snakeDeeplinePricingDetails,
48742
48805
  ...publicTool
48743
48806
  } = tool;
48807
+ const outputSchemaRecord = recordField2(tool, "outputSchema", "output_schema");
48744
48808
  return {
48745
48809
  ...publicTool,
48746
48810
  toolId,
48747
48811
  provider: tool.provider,
48748
48812
  displayName: tool.displayName,
48813
+ ...Object.keys(outputSchemaRecord).length > 0 ? {
48814
+ outputSchema: publicToolInputSchemaForDescribe(outputSchemaRecord),
48815
+ outputFields: toolOutputFieldsForDisplay(outputSchemaRecord).map(
48816
+ inputFieldJsonForDescribe
48817
+ )
48818
+ } : {},
48819
+ inputFields: inputFields.map(inputFieldJsonForDescribe),
48749
48820
  cost: Capability.fromCatalogEntry(tool).describe().customerCost(),
48750
48821
  usageGuidance,
48751
48822
  runtimeOutputHelp: {
@@ -48804,8 +48875,27 @@ function formatListedToolCost(tool) {
48804
48875
  return displayText ? `Cost: ${displayText}` : "";
48805
48876
  }
48806
48877
  function toolInputFieldsForDisplay(inputSchema) {
48807
- if (Array.isArray(inputSchema.fields))
48808
- return inputSchema.fields.filter(isRecord12);
48878
+ if (Array.isArray(inputSchema.fields)) {
48879
+ const fields = inputSchema.fields.filter(isRecord12);
48880
+ if (!isRecord12(inputSchema.jsonSchema)) return fields;
48881
+ const jsonSchemaFields = new Map(
48882
+ recursiveToolInputFieldsForDisplay({
48883
+ jsonSchema: inputSchema.jsonSchema
48884
+ }).flatMap(
48885
+ (field) => typeof field.name === "string" ? [[field.name, field]] : []
48886
+ )
48887
+ );
48888
+ return fields.map((field) => {
48889
+ const jsonSchemaField = typeof field.name === "string" ? jsonSchemaFields.get(field.name) : void 0;
48890
+ const minItems = typeof field.minItems === "number" ? field.minItems : jsonSchemaField?.minItems;
48891
+ const maxItems = typeof field.maxItems === "number" ? field.maxItems : jsonSchemaField?.maxItems;
48892
+ return {
48893
+ ...field,
48894
+ ...typeof minItems === "number" ? { minItems } : {},
48895
+ ...typeof maxItems === "number" ? { maxItems } : {}
48896
+ };
48897
+ });
48898
+ }
48809
48899
  const jsonSchema = isRecord12(inputSchema.jsonSchema) ? inputSchema.jsonSchema : inputSchema;
48810
48900
  const properties = isRecord12(jsonSchema.properties) ? jsonSchema.properties : {};
48811
48901
  const required = Array.isArray(jsonSchema.required) ? new Set(jsonSchema.required.map(String)) : /* @__PURE__ */ new Set();
@@ -48816,10 +48906,36 @@ function toolInputFieldsForDisplay(inputSchema) {
48816
48906
  type: typeof property.type === "string" ? property.type : "unknown",
48817
48907
  required: required.has(name),
48818
48908
  description: property.description,
48909
+ ...typeof property.minItems === "number" ? { minItems: property.minItems } : {},
48910
+ ...typeof property.maxItems === "number" ? { maxItems: property.maxItems } : {},
48819
48911
  ...Object.prototype.hasOwnProperty.call(property, "default") ? { default: property.default } : {}
48820
48912
  };
48821
48913
  });
48822
48914
  }
48915
+ function toolOutputFieldsForDisplay(outputSchema) {
48916
+ if (Object.keys(outputSchema).length === 0) return [];
48917
+ return recursiveToolInputFieldsForDisplay({
48918
+ jsonSchema: outputSchema
48919
+ }).filter(
48920
+ (field) => typeof field.name === "string" && field.name.includes("[]")
48921
+ );
48922
+ }
48923
+ function printToolOutputArrayShape(tool) {
48924
+ const outputFields = toolOutputFieldsForDisplay(
48925
+ recordField2(isRecord12(tool) ? tool : {}, "outputSchema", "output_schema")
48926
+ );
48927
+ if (outputFields.length === 0) return;
48928
+ console.log(" Output array shape (declared schema):");
48929
+ for (const field of outputFields.slice(0, 60)) {
48930
+ const name = String(field.name);
48931
+ const type = stringField2(field, "type") || "unknown";
48932
+ const itemBounds = arrayItemBoundsSuffix(field);
48933
+ console.log(` - ${name}: ${type}${itemBounds}`);
48934
+ }
48935
+ if (outputFields.length > 60) {
48936
+ console.log(` - \u2026 ${outputFields.length - 60} more schema fields`);
48937
+ }
48938
+ }
48823
48939
  function canonicalToolJsonSchema(inputSchema) {
48824
48940
  return isRecord12(inputSchema.jsonSchema) ? inputSchema.jsonSchema : inputSchema;
48825
48941
  }
@@ -48909,6 +49025,8 @@ function recursiveToolInputFieldsForDisplay(inputSchema) {
48909
49025
  required,
48910
49026
  description: schema.description,
48911
49027
  ...Array.isArray(schema.enum) ? { enum: schema.enum } : {},
49028
+ ...typeof schema.minItems === "number" ? { minItems: schema.minItems } : {},
49029
+ ...typeof schema.maxItems === "number" ? { maxItems: schema.maxItems } : {},
48912
49030
  ...Object.prototype.hasOwnProperty.call(schema, "default") ? { default: schema.default } : {}
48913
49031
  });
48914
49032
  }
@@ -48940,6 +49058,121 @@ function recursiveToolInputFieldsForDisplay(inputSchema) {
48940
49058
  visit(root, "", false);
48941
49059
  return fields.size ? [...fields.values()] : toolInputFieldsForDisplay(inputSchema);
48942
49060
  }
49061
+ function inputFieldJsonForDescribe(field) {
49062
+ return {
49063
+ name: field.name,
49064
+ type: field.type ?? "unknown",
49065
+ required: Boolean(field.required),
49066
+ ...field.description ? { description: field.description } : {},
49067
+ ...typeof field.minItems === "number" ? { minItems: field.minItems } : {},
49068
+ ...typeof field.maxItems === "number" ? { maxItems: field.maxItems } : {},
49069
+ ...Object.prototype.hasOwnProperty.call(field, "default") ? { default: field.default } : {}
49070
+ };
49071
+ }
49072
+ function arrayItemBoundsSuffix(field) {
49073
+ const minItems = typeof field.minItems === "number" && Number.isFinite(field.minItems) ? field.minItems : null;
49074
+ const maxItems = typeof field.maxItems === "number" && Number.isFinite(field.maxItems) ? field.maxItems : null;
49075
+ if (minItems !== null && maxItems !== null) {
49076
+ return ` items=${minItems}..${maxItems}`;
49077
+ }
49078
+ if (minItems !== null) return ` minItems=${minItems}`;
49079
+ if (maxItems !== null) return ` maxItems=${maxItems}`;
49080
+ return "";
49081
+ }
49082
+ function printToolExecutionHints(value) {
49083
+ const batchCapabilityRecord = recordField2(
49084
+ isRecord12(value) ? value : {},
49085
+ "batchCapability",
49086
+ "batch_capability"
49087
+ );
49088
+ const batchCapability = Object.keys(batchCapabilityRecord).length > 0 ? batchCapabilityRecord : null;
49089
+ const executionMetadata = recordField2(
49090
+ isRecord12(value) ? value : {},
49091
+ "executionMetadata",
49092
+ "execution_metadata"
49093
+ );
49094
+ if (batchCapability) {
49095
+ const status = stringField2(batchCapability, "status") || "unknown";
49096
+ const surface = stringField2(batchCapability, "surface");
49097
+ const operation = stringField2(
49098
+ batchCapability,
49099
+ "batchOperation",
49100
+ "batch_operation"
49101
+ );
49102
+ const maxBatchSize = numberField2(
49103
+ batchCapability,
49104
+ "maxBatchSize",
49105
+ "max_batch_size"
49106
+ );
49107
+ const notes = stringField2(batchCapability, "notes");
49108
+ console.log("");
49109
+ console.log("Batching:");
49110
+ console.log(`- Catalog status: ${status}${surface ? ` (${surface})` : ""}`);
49111
+ if (operation) console.log(`- Batch operation: ${operation}`);
49112
+ if (maxBatchSize !== null) {
49113
+ console.log(`- Maximum batch size: ${maxBatchSize} items`);
49114
+ }
49115
+ if (status === "compiled") {
49116
+ console.log(
49117
+ "- Compatible per-row Play calls can coalesce; separate tools execute requests do not coalesce."
49118
+ );
49119
+ } else if (surface !== "docs") {
49120
+ console.log(
49121
+ "- Play does not automatically coalesce per-row calls for this operation; send a native batch as one request when its input schema supports one."
49122
+ );
49123
+ }
49124
+ if (notes) console.log(`- Details: ${notes}`);
49125
+ }
49126
+ const configuredRateLimits = arrayField2(
49127
+ executionMetadata,
49128
+ "configuredRateLimits",
49129
+ "configured_rate_limits"
49130
+ ).filter(isRecord12);
49131
+ if (configuredRateLimits.length > 0) {
49132
+ console.log("");
49133
+ console.log(
49134
+ "Configured Deepline pacing (guidance, not a guaranteed provider quota):"
49135
+ );
49136
+ for (const limit of configuredRateLimits) {
49137
+ const requests = numberField2(limit, "requestsPerWindow");
49138
+ const windowMs = numberField2(limit, "windowMs");
49139
+ if (requests === null || windowMs === null) continue;
49140
+ const usage = stringField2(limit, "usage") || "unknown";
49141
+ const usageText = usage === "queue_hint" ? "queue hint" : usage === "enforced" ? "Deepline enforced" : usage === "queue_hint_and_enforced" ? "queue hint and Deepline enforced" : usage === "disabled" ? "disabled" : usage;
49142
+ const explicitMaxConcurrency = numberField2(
49143
+ limit,
49144
+ "explicitMaxConcurrency",
49145
+ "explicit_max_concurrency"
49146
+ );
49147
+ const concurrencyText = explicitMaxConcurrency === null ? "no explicit concurrency limit" : `explicit concurrency limit ${explicitMaxConcurrency}`;
49148
+ console.log(
49149
+ `- ${requests} requests per ${formatRateWindow(windowMs)} (${usageText}; ${concurrencyText})`
49150
+ );
49151
+ }
49152
+ }
49153
+ const queueHint = recordField2(executionMetadata, "queueHint", "queue_hint");
49154
+ const requestsPerSecondHint = numberField2(
49155
+ queueHint,
49156
+ "requestsPerSecondHint",
49157
+ "requests_per_second_hint"
49158
+ );
49159
+ const derivedConcurrency = numberField2(
49160
+ queueHint,
49161
+ "derivedConcurrency",
49162
+ "derived_concurrency"
49163
+ );
49164
+ if (requestsPerSecondHint !== null && requestsPerSecondHint > 0 && derivedConcurrency !== null) {
49165
+ console.log(
49166
+ `Derived runtime queue hint: ${requestsPerSecondHint} requests/second; ${derivedConcurrency} derived concurrency. This is not an observed provider concurrency limit.`
49167
+ );
49168
+ }
49169
+ }
49170
+ function formatRateWindow(windowMs) {
49171
+ if (windowMs === 1e3) return "second";
49172
+ if (windowMs === 6e4) return "minute";
49173
+ if (windowMs === 36e5) return "hour";
49174
+ return `${windowMs}ms`;
49175
+ }
48943
49176
  function printSamples(samples) {
48944
49177
  const requestPayload = samplePayload(samples, "request");
48945
49178
  const responsePayload = samplePayload(samples, "response");
@@ -50926,6 +51159,8 @@ Examples:
50926
51159
  printJsonError(error);
50927
51160
  } else if (error instanceof Error) {
50928
51161
  console.error(`Error: ${error.message}`);
51162
+ const providerConcurrency = formatProviderConcurrencyDiagnostic(error);
51163
+ if (providerConcurrency) console.error(providerConcurrency);
50929
51164
  } else {
50930
51165
  console.error(`Error: ${String(error)}`);
50931
51166
  }
package/dist/index.d.mts CHANGED
@@ -1162,9 +1162,9 @@ interface ProviderDefinition {
1162
1162
  *
1163
1163
  * Returned by {@link DeeplineClient.listTools} and ranked tool search. Use
1164
1164
  * `getTool(toolId)` or the matching HTTP describe route for provider-specific
1165
- * schema, examples, pricing, and extraction guidance before executing.
1165
+ * schema, examples, pricing, extraction guidance, and execution metadata.
1166
1166
  */
1167
- interface ToolDefinition {
1167
+ interface ToolDefinition extends ToolExecutionMetadataFields {
1168
1168
  /** Unique tool identifier used in API calls (e.g. `"dropleads_search_people"`). */
1169
1169
  toolId: string;
1170
1170
  /** Provider that backs this tool (e.g. `"hunter"`, `"dropleads"`, `"test"`). */
@@ -1299,6 +1299,42 @@ interface ToolDefinition {
1299
1299
  /** Actionable message shown when a connection is required. */
1300
1300
  connectionMessage?: string;
1301
1301
  }
1302
+ type ToolBatchCapability = {
1303
+ status: 'compiled' | 'exposed_uncompiled' | 'upstream_only';
1304
+ surface: 'registry' | 'local' | 'docs';
1305
+ batchKind: 'identifier_batch' | 'query_share' | 'async_dataset_job';
1306
+ batchOperation: string | null;
1307
+ maxBatchSize: number | null;
1308
+ notes: string;
1309
+ };
1310
+ /** Optional batching, pacing, and configured rate metadata for tool catalog entries. */
1311
+ interface ToolExecutionMetadataFields {
1312
+ batchCapability?: ToolBatchCapability;
1313
+ batch_capability?: ToolBatchCapability;
1314
+ executionMetadata?: ToolExecutionMetadata;
1315
+ execution_metadata?: ToolExecutionMetadata;
1316
+ }
1317
+ type ToolExecutionMetadata = {
1318
+ provider: string;
1319
+ sourceOperation: string;
1320
+ effectiveOperation: string;
1321
+ batch: {
1322
+ batchOperation: string | null;
1323
+ maxBatchSize: number;
1324
+ };
1325
+ configuredRateLimits: Array<{
1326
+ source: 'deepline_configuration';
1327
+ scope: string;
1328
+ requestsPerWindow: number;
1329
+ windowMs: number;
1330
+ usage: 'queue_hint' | 'enforced' | 'queue_hint_and_enforced' | 'disabled';
1331
+ explicitMaxConcurrency: number | null;
1332
+ }>;
1333
+ queueHint: {
1334
+ requestsPerSecondHint: number;
1335
+ derivedConcurrency: number;
1336
+ };
1337
+ };
1302
1338
  interface ModelProviderOptionField {
1303
1339
  name: string;
1304
1340
  type: 'string' | 'number' | 'boolean' | 'object' | 'array';
@@ -1655,6 +1691,11 @@ interface PlayRunPackage {
1655
1691
  startedAt?: number | null;
1656
1692
  finishedAt?: number | null;
1657
1693
  durationMs?: number | null;
1694
+ outcome?: PlayRunOutcome;
1695
+ recovery?: {
1696
+ mode: 'replayed' | 'forced' | 'recovered' | 'joined';
1697
+ sourceRunId?: string;
1698
+ };
1658
1699
  error?: string;
1659
1700
  /** Canonical explanation of what this run is doing or waiting on. */
1660
1701
  activity?: PlayRunActivityProjection | null;
@@ -1699,6 +1740,11 @@ interface PlayRunPackage {
1699
1740
  logs?: PlayRunActionPackage;
1700
1741
  };
1701
1742
  }
1743
+ /**
1744
+ * Stable classification of whether this run executed work or reused/recovered
1745
+ * an existing durable run outcome.
1746
+ */
1747
+ type PlayRunOutcome = 'executed' | 'reused' | 'joined' | 'recovered' | 'forced' | 'waiting' | 'failed';
1702
1748
  /**
1703
1749
  * Current status of a play execution, returned by {@link DeeplineClient.getPlayStatus}.
1704
1750
  *
@@ -1730,6 +1776,12 @@ interface PlayStatus {
1730
1776
  dashboardUrl?: string;
1731
1777
  /** Product-level play-run state. */
1732
1778
  status: 'queued' | 'running' | 'waiting' | 'completed' | 'failed' | 'cancelled';
1779
+ /** How this run was admitted or recovered, when the server can prove it. */
1780
+ outcome?: PlayRunOutcome;
1781
+ recovery?: {
1782
+ mode: 'replayed' | 'forced' | 'recovered' | 'joined';
1783
+ sourceRunId?: string;
1784
+ };
1733
1785
  /** Execution progress with logs and error details. */
1734
1786
  progress?: PlayProgressStatus;
1735
1787
  /** Partial or final result. Available once the play returns. */
@@ -4102,6 +4154,20 @@ type TargetBillingStatusResult = {
4102
4154
  legacy_changes_allowed?: boolean;
4103
4155
  payment_state: string;
4104
4156
  recharge_state: string;
4157
+ billing_email?: string | null;
4158
+ collection_method?: 'charge_automatically' | 'send_invoice';
4159
+ payment_access_policy?: 'payment_required' | 'net_30' | 'net_60';
4160
+ plan_invoice?: {
4161
+ url: string | null;
4162
+ amount_usd: number;
4163
+ due_at: string | null;
4164
+ status: string | null;
4165
+ } | null;
4166
+ outstanding_invoice?: {
4167
+ amount_usd: number;
4168
+ due_at: string;
4169
+ state: 'open' | 'cancelling';
4170
+ } | null;
4105
4171
  next_action: string | null;
4106
4172
  pending_plan_sku: string | null;
4107
4173
  /** Saved transition boundary; optional for older servers. */
@@ -4144,6 +4210,7 @@ type TargetBillingMutationResult = {
4144
4210
  type TargetBillingPlanTransitionOptions = {
4145
4211
  action: 'start_or_change';
4146
4212
  targetPlanSku: 'payg-v1' | 'builder-v1' | 'growth-v1' | 'growth-canary-v1' | 'team-v1';
4213
+ billingEmail?: string;
4147
4214
  idempotencyKey: string;
4148
4215
  } | {
4149
4216
  action: 'cancel' | 'undo_cancel';
package/dist/index.d.ts CHANGED
@@ -1162,9 +1162,9 @@ interface ProviderDefinition {
1162
1162
  *
1163
1163
  * Returned by {@link DeeplineClient.listTools} and ranked tool search. Use
1164
1164
  * `getTool(toolId)` or the matching HTTP describe route for provider-specific
1165
- * schema, examples, pricing, and extraction guidance before executing.
1165
+ * schema, examples, pricing, extraction guidance, and execution metadata.
1166
1166
  */
1167
- interface ToolDefinition {
1167
+ interface ToolDefinition extends ToolExecutionMetadataFields {
1168
1168
  /** Unique tool identifier used in API calls (e.g. `"dropleads_search_people"`). */
1169
1169
  toolId: string;
1170
1170
  /** Provider that backs this tool (e.g. `"hunter"`, `"dropleads"`, `"test"`). */
@@ -1299,6 +1299,42 @@ interface ToolDefinition {
1299
1299
  /** Actionable message shown when a connection is required. */
1300
1300
  connectionMessage?: string;
1301
1301
  }
1302
+ type ToolBatchCapability = {
1303
+ status: 'compiled' | 'exposed_uncompiled' | 'upstream_only';
1304
+ surface: 'registry' | 'local' | 'docs';
1305
+ batchKind: 'identifier_batch' | 'query_share' | 'async_dataset_job';
1306
+ batchOperation: string | null;
1307
+ maxBatchSize: number | null;
1308
+ notes: string;
1309
+ };
1310
+ /** Optional batching, pacing, and configured rate metadata for tool catalog entries. */
1311
+ interface ToolExecutionMetadataFields {
1312
+ batchCapability?: ToolBatchCapability;
1313
+ batch_capability?: ToolBatchCapability;
1314
+ executionMetadata?: ToolExecutionMetadata;
1315
+ execution_metadata?: ToolExecutionMetadata;
1316
+ }
1317
+ type ToolExecutionMetadata = {
1318
+ provider: string;
1319
+ sourceOperation: string;
1320
+ effectiveOperation: string;
1321
+ batch: {
1322
+ batchOperation: string | null;
1323
+ maxBatchSize: number;
1324
+ };
1325
+ configuredRateLimits: Array<{
1326
+ source: 'deepline_configuration';
1327
+ scope: string;
1328
+ requestsPerWindow: number;
1329
+ windowMs: number;
1330
+ usage: 'queue_hint' | 'enforced' | 'queue_hint_and_enforced' | 'disabled';
1331
+ explicitMaxConcurrency: number | null;
1332
+ }>;
1333
+ queueHint: {
1334
+ requestsPerSecondHint: number;
1335
+ derivedConcurrency: number;
1336
+ };
1337
+ };
1302
1338
  interface ModelProviderOptionField {
1303
1339
  name: string;
1304
1340
  type: 'string' | 'number' | 'boolean' | 'object' | 'array';
@@ -1655,6 +1691,11 @@ interface PlayRunPackage {
1655
1691
  startedAt?: number | null;
1656
1692
  finishedAt?: number | null;
1657
1693
  durationMs?: number | null;
1694
+ outcome?: PlayRunOutcome;
1695
+ recovery?: {
1696
+ mode: 'replayed' | 'forced' | 'recovered' | 'joined';
1697
+ sourceRunId?: string;
1698
+ };
1658
1699
  error?: string;
1659
1700
  /** Canonical explanation of what this run is doing or waiting on. */
1660
1701
  activity?: PlayRunActivityProjection | null;
@@ -1699,6 +1740,11 @@ interface PlayRunPackage {
1699
1740
  logs?: PlayRunActionPackage;
1700
1741
  };
1701
1742
  }
1743
+ /**
1744
+ * Stable classification of whether this run executed work or reused/recovered
1745
+ * an existing durable run outcome.
1746
+ */
1747
+ type PlayRunOutcome = 'executed' | 'reused' | 'joined' | 'recovered' | 'forced' | 'waiting' | 'failed';
1702
1748
  /**
1703
1749
  * Current status of a play execution, returned by {@link DeeplineClient.getPlayStatus}.
1704
1750
  *
@@ -1730,6 +1776,12 @@ interface PlayStatus {
1730
1776
  dashboardUrl?: string;
1731
1777
  /** Product-level play-run state. */
1732
1778
  status: 'queued' | 'running' | 'waiting' | 'completed' | 'failed' | 'cancelled';
1779
+ /** How this run was admitted or recovered, when the server can prove it. */
1780
+ outcome?: PlayRunOutcome;
1781
+ recovery?: {
1782
+ mode: 'replayed' | 'forced' | 'recovered' | 'joined';
1783
+ sourceRunId?: string;
1784
+ };
1733
1785
  /** Execution progress with logs and error details. */
1734
1786
  progress?: PlayProgressStatus;
1735
1787
  /** Partial or final result. Available once the play returns. */
@@ -4102,6 +4154,20 @@ type TargetBillingStatusResult = {
4102
4154
  legacy_changes_allowed?: boolean;
4103
4155
  payment_state: string;
4104
4156
  recharge_state: string;
4157
+ billing_email?: string | null;
4158
+ collection_method?: 'charge_automatically' | 'send_invoice';
4159
+ payment_access_policy?: 'payment_required' | 'net_30' | 'net_60';
4160
+ plan_invoice?: {
4161
+ url: string | null;
4162
+ amount_usd: number;
4163
+ due_at: string | null;
4164
+ status: string | null;
4165
+ } | null;
4166
+ outstanding_invoice?: {
4167
+ amount_usd: number;
4168
+ due_at: string;
4169
+ state: 'open' | 'cancelling';
4170
+ } | null;
4105
4171
  next_action: string | null;
4106
4172
  pending_plan_sku: string | null;
4107
4173
  /** Saved transition boundary; optional for older servers. */
@@ -4144,6 +4210,7 @@ type TargetBillingMutationResult = {
4144
4210
  type TargetBillingPlanTransitionOptions = {
4145
4211
  action: 'start_or_change';
4146
4212
  targetPlanSku: 'payg-v1' | 'builder-v1' | 'growth-v1' | 'growth-canary-v1' | 'team-v1';
4213
+ billingEmail?: string;
4147
4214
  idempotencyKey: string;
4148
4215
  } | {
4149
4216
  action: 'cancel' | 'undo_cancel';
package/dist/index.js CHANGED
@@ -864,7 +864,7 @@ var SDK_RELEASE = {
864
864
  // getters keep their established compatibility behavior.
865
865
  // 0.3.1 deprecated the legacy `deepline enrich` command in favor of Plays.
866
866
  // 0.3.90 is the first deliberately versioned SDK release for API v3.
867
- version: "0.3.140",
867
+ version: "0.3.142",
868
868
  updateSummary: "Play grep now returns concise results with the matched fields and terms. Automatic CLI updates are enabled by default; use `deepline settings autoupdate off` to opt out, `deepline settings autoupdate on` to re-enable updates, or `deepline settings autoupdate pin <version>` to hold an exact release.",
869
869
  packageCapabilities: {
870
870
  updatePreferences: 1
@@ -7304,6 +7304,7 @@ var DeeplineClient = class _DeeplineClient {
7304
7304
  "/api/v2/billing/plan-transitions",
7305
7305
  {
7306
7306
  action: options.action,
7307
+ ...options.action === "start_or_change" && options.billingEmail ? { billing_email: options.billingEmail } : {},
7307
7308
  ...options.targetPlanSku ? { target_plan_sku: options.targetPlanSku } : {}
7308
7309
  },
7309
7310
  { "Idempotency-Key": idempotencyKey },