deepline 0.1.46 → 0.1.48

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.
package/README.md CHANGED
@@ -50,10 +50,10 @@ cd sdk && bun run build # or: npm run sdk:build from root
50
50
 
51
51
  ## Env files
52
52
 
53
- | File | Set by | Contains |
54
- | ------------------------------------ | ------------------- | ----------------------------------------- |
55
- | `~/.local/deepline/<host-slug>/.env` | SDK `auth register` | `DEEPLINE_HOST_URL`, `DEEPLINE_API_KEY` |
56
- | `.env.deepline` | Developer/agent | `DEEPLINE_HOST_URL`, `DEEPLINE_API_KEY` |
53
+ | File | Set by | Contains |
54
+ | ------------------------------------ | ------------------- | --------------------------------------- |
55
+ | `~/.local/deepline/<host-slug>/.env` | SDK `auth register` | `DEEPLINE_HOST_URL`, `DEEPLINE_API_KEY` |
56
+ | `.env.deepline` | Developer/agent | `DEEPLINE_HOST_URL`, `DEEPLINE_API_KEY` |
57
57
 
58
58
  The SDK CLI env contract is only `DEEPLINE_HOST_URL` and `DEEPLINE_API_KEY`.
59
59
  Do not route the SDK CLI through `.env`, `.env.local`, or `.env.worktree`.
@@ -257,27 +257,27 @@ export default definePlay('rate-limit-waterfall', async (ctx) => {
257
257
 
258
258
  const probeFallback = steps<{ lead_id: string; row_number: number }>()
259
259
  .step("primary_probe", (row, ctx) =>
260
- ctx.tool({
260
+ ctx.tools.execute({
261
261
  id: 'rate_limit_probe',
262
262
  tool: 'test_rate_limit',
263
263
  input: {
264
- key: 'redis-shared-scenario',
265
- lead_id: row.lead_id,
266
- row_number: row.row_number,
267
- },
264
+ key: 'redis-shared-scenario',
265
+ lead_id: row.lead_id,
266
+ row_number: row.row_number,
267
+ },
268
268
  description: 'Exercise primary rate-limit behavior.',
269
269
  }))
270
270
  .step("backup_probe", when(
271
271
  (row) => !row.primary_probe,
272
272
  (row, ctx) =>
273
- ctx.tool({
273
+ ctx.tools.execute({
274
274
  id: 'rate_limit_probe_backup',
275
275
  tool: 'test_rate_limit',
276
276
  input: {
277
- key: 'redis-shared-scenario',
278
- lead_id: row.lead_id,
279
- row_number: row.row_number,
280
- },
277
+ key: 'redis-shared-scenario',
278
+ lead_id: row.lead_id,
279
+ row_number: row.row_number,
280
+ },
281
281
  description: 'Exercise fallback rate-limit behavior.',
282
282
  }),
283
283
  ))
package/dist/cli/index.js CHANGED
@@ -216,7 +216,7 @@ function resolveConfig(options) {
216
216
  }
217
217
 
218
218
  // src/version.ts
219
- var SDK_VERSION = "0.1.46";
219
+ var SDK_VERSION = "0.1.48";
220
220
  var SDK_API_CONTRACT = "2026-05-stripe-promo-checkout";
221
221
 
222
222
  // ../shared_libs/play-runtime/coordinator-headers.ts
@@ -2795,8 +2795,10 @@ async function handleCheckout(options) {
2795
2795
  }
2796
2796
  async function handleRedeemCode(code, options) {
2797
2797
  const { http } = getAuthedHttpClient();
2798
- const payload = await http.post("/api/v2/billing/checkout/verify", { code });
2799
- const url = String(payload.url || "");
2798
+ const payload = await http.post("/api/v2/billing/checkout", {
2799
+ discountCode: code
2800
+ });
2801
+ const url = String(payload.url || payload.checkout_url || "");
2800
2802
  if (!options.json && !options.noOpen && url) openInBrowser(url);
2801
2803
  printCommandEnvelope({
2802
2804
  ...payload,
@@ -9232,11 +9234,16 @@ function extractSummaryFields(payload) {
9232
9234
  }
9233
9235
 
9234
9236
  // src/cli/commands/tools.ts
9237
+ var TOOL_COMMAND_TEMPLATES = {
9238
+ describe: "deepline tools describe <toolId>",
9239
+ execute: "deepline tools execute <toolId> --input '{...}'"
9240
+ };
9235
9241
  function toListedTool(tool) {
9236
9242
  if (isPlayLikeTool(tool)) {
9237
9243
  const playReference = playReferenceForTool(tool);
9238
9244
  return {
9239
9245
  ...tool,
9246
+ description: listedToolDescription(tool),
9240
9247
  id: tool.toolId,
9241
9248
  type: "play",
9242
9249
  executeCommand: `deepline plays run ${playReference} --input '{...}' --watch`
@@ -9244,6 +9251,7 @@ function toListedTool(tool) {
9244
9251
  }
9245
9252
  return {
9246
9253
  ...tool,
9254
+ description: listedToolDescription(tool),
9247
9255
  id: tool.toolId,
9248
9256
  type: "tool",
9249
9257
  executeCommand: `deepline tools execute ${tool.toolId}`
@@ -9256,14 +9264,29 @@ async function listTools(args) {
9256
9264
  sections: [
9257
9265
  {
9258
9266
  title: `${items.length} tools available:`,
9259
- lines: items.flatMap((item) => {
9267
+ lines: items.map((item) => {
9260
9268
  const cats = item.categories.length ? ` [${item.categories.join(", ")}]` : "";
9261
- return [`${item.toolId}${cats}`, ` ${item.description}`];
9269
+ const pricing = formatListedToolCost(item);
9270
+ return `${item.toolId}${cats} - ${item.description}${pricing ? ` - ${pricing}` : ""}`;
9262
9271
  })
9272
+ },
9273
+ {
9274
+ title: "next",
9275
+ lines: [
9276
+ "Run `deepline tools describe <toolId>` before executing a tool."
9277
+ ]
9263
9278
  }
9264
9279
  ]
9265
9280
  };
9266
- printCommandEnvelope({ tools: items, count: items.length, render }, { json: argsWantJson(args) });
9281
+ printCommandEnvelope(
9282
+ {
9283
+ tools: items,
9284
+ count: items.length,
9285
+ commandTemplates: TOOL_COMMAND_TEMPLATES,
9286
+ render
9287
+ },
9288
+ { json: argsWantJson(args) }
9289
+ );
9267
9290
  return 0;
9268
9291
  }
9269
9292
  async function searchTools(queryInput, options = {}) {
@@ -9481,8 +9504,22 @@ async function getTool(args) {
9481
9504
  }
9482
9505
  function toolMetadataJsonForDescribe(tool, requestedToolId) {
9483
9506
  const toolId = String(tool.toolId || requestedToolId);
9507
+ const {
9508
+ cost: _cost,
9509
+ deeplineCreditsPerPricingUnit: _deeplineCreditsPerPricingUnit,
9510
+ deeplineUsdPerPricingUnit: _deeplineUsdPerPricingUnit,
9511
+ deeplineUsdPerCredit: _deeplineUsdPerCredit,
9512
+ deeplinePricingSummary: _deeplinePricingSummary,
9513
+ deeplinePricingDetails: _deeplinePricingDetails,
9514
+ deepline_credits_per_pricing_unit: _snakeDeeplineCreditsPerPricingUnit,
9515
+ deepline_usd_per_pricing_unit: _snakeDeeplineUsdPerPricingUnit,
9516
+ deepline_usd_per_credit: _snakeDeeplineUsdPerCredit,
9517
+ deepline_pricing_summary: _snakeDeeplinePricingSummary,
9518
+ deepline_pricing_details: _snakeDeeplinePricingDetails,
9519
+ ...publicTool
9520
+ } = tool;
9484
9521
  return {
9485
- ...tool,
9522
+ ...publicTool,
9486
9523
  toolId,
9487
9524
  provider: tool.provider,
9488
9525
  displayName: tool.displayName,
@@ -9501,9 +9538,9 @@ function printToolDetails(tool, requestedToolId) {
9501
9538
  const displayBase = operation && operation.startsWith(`${tool.provider}_`) ? operation.slice(String(tool.provider).length + 1) : operation ? `${tool.provider} ${operation}`.trim() : toolId;
9502
9539
  const displayName = titleCase(displayBase || String(tool.displayName || toolId));
9503
9540
  const cost = isRecord4(tool.cost) ? tool.cost : null;
9541
+ const pricing = recordField(tool, "pricing");
9504
9542
  const deeplineCredits = numberField(tool, "deeplineCreditsPerPricingUnit", "deepline_credits_per_pricing_unit");
9505
9543
  const deeplineUsdPerPricingUnit = numberField(tool, "deeplineUsdPerPricingUnit", "deepline_usd_per_pricing_unit");
9506
- const deeplineUsdPerCredit = numberField(tool, "deeplineUsdPerCredit", "deepline_usd_per_credit");
9507
9544
  const billingSource = stringField(tool, "billingSource", "billing_source");
9508
9545
  const billingSourceLabel = stringField(tool, "billingSourceLabel", "billing_source_label");
9509
9546
  const estimatedCreditsRange = stringField(tool, "estimatedCreditsRange", "estimated_credits_range");
@@ -9528,6 +9565,7 @@ function printToolDetails(tool, requestedToolId) {
9528
9565
  console.log(` ${tool.categories.join(", ")}`);
9529
9566
  }
9530
9567
  const printedCost = printToolCost({
9568
+ pricing,
9531
9569
  cost,
9532
9570
  billingSource,
9533
9571
  deeplineCredits,
@@ -9539,9 +9577,6 @@ function printToolDetails(tool, requestedToolId) {
9539
9577
  if (billingSourceLabel) {
9540
9578
  console.log(` Billing source: ${billingSourceLabel}`);
9541
9579
  }
9542
- if (typeof deeplineUsdPerCredit === "number") {
9543
- console.log(` Deepline rate: $${deeplineUsdPerCredit.toFixed(2)} per credit`);
9544
- }
9545
9580
  if (estimatedCreditsRange) {
9546
9581
  const usdSuffix = estimatedUsdRange ? ` (~${estimatedUsdRange})` : "";
9547
9582
  console.log(` Estimated play spend: ${estimatedCreditsRange}${usdSuffix}`);
@@ -9643,29 +9678,54 @@ function printExtractions(label, entries) {
9643
9678
  console.log(` - ${name}: ${expression}${pathSuffix}`);
9644
9679
  }
9645
9680
  }
9681
+ function singleLineText(value, maxLength = 260) {
9682
+ if (typeof value !== "string") return "";
9683
+ const text = value.replace(/\s+/g, " ").trim();
9684
+ if (text.length <= maxLength) return text;
9685
+ return `${text.slice(0, maxLength - 3).trimEnd()}...`;
9686
+ }
9687
+ function listedToolDescription(tool) {
9688
+ const record = tool;
9689
+ return singleLineText(record.bestFor ?? record.best_for ?? tool.description);
9690
+ }
9691
+ function formatListedToolCost(tool) {
9692
+ const record = tool;
9693
+ const pricing = recordField(record, "pricing");
9694
+ const displayText = stringField(pricing, "displayText", "display_text");
9695
+ return displayText ? `Cost: ${displayText}` : "";
9696
+ }
9646
9697
  function printToolCost(input) {
9647
- const { cost, billingSource, deeplineCredits, deeplineUsdPerPricingUnit } = input;
9648
- if (!cost) return false;
9649
- const pricingModel = typeof cost.pricingModel === "string" ? cost.pricingModel : typeof cost.pricing_model === "string" ? cost.pricing_model : "";
9650
- const billingMode = typeof cost.billingMode === "string" ? cost.billingMode : typeof cost.billing_mode === "string" ? cost.billing_mode : "";
9651
- const providerPrice = typeof cost.providerPricePerPricingModel === "number" ? cost.providerPricePerPricingModel : null;
9652
- if (pricingModel === "fixed" && providerPrice === 0) {
9653
- console.log(" Cost: free");
9654
- return true;
9655
- }
9698
+ const { pricing, cost, billingSource, deeplineCredits, deeplineUsdPerPricingUnit } = input;
9656
9699
  if (billingSource === "own_provider_credentials") {
9657
9700
  console.log(" Cost: free through Deepline");
9658
9701
  return true;
9659
9702
  }
9660
- if (pricingModel && billingMode && deeplineCredits !== null) {
9703
+ const displayText = stringField(pricing, "displayText", "display_text");
9704
+ if (displayText) {
9705
+ console.log(` Cost: ${displayText}`);
9706
+ const details = arrayField(pricing, "details").map((item) => String(item).trim()).filter(Boolean);
9707
+ if (details.length) {
9708
+ console.log(" notes:");
9709
+ for (const detail of details) console.log(` - ${detail}`);
9710
+ }
9711
+ return true;
9712
+ }
9713
+ const pricingModel = cost ? typeof cost.pricingModel === "string" ? cost.pricingModel : typeof cost.pricing_model === "string" ? cost.pricing_model : "" : "";
9714
+ const billingMode = cost ? typeof cost.billingMode === "string" ? cost.billingMode : typeof cost.billing_mode === "string" ? cost.billing_mode : "" : "";
9715
+ if (deeplineCredits === 0) {
9716
+ console.log(" Cost: Free");
9717
+ return true;
9718
+ }
9719
+ if (pricingModel && deeplineCredits !== null) {
9661
9720
  const unit = pricingModel === "per_page" ? "page" : pricingModel === "per_result" ? "result" : "call";
9662
9721
  const usdText = deeplineUsdPerPricingUnit !== null ? ` / ${formatUsd(deeplineUsdPerPricingUnit)}` : "";
9663
- console.log(` Cost: ${formatDecimal(deeplineCredits)} Deepline credits${usdText} per ${unit} (${billingMode})`);
9722
+ const billingSuffix = billingMode ? ` (${billingMode})` : "";
9723
+ console.log(` Cost: ${formatDecimal(deeplineCredits)} Deepline credits${usdText} per ${unit}${billingSuffix}`);
9664
9724
  return true;
9665
9725
  }
9666
- if (pricingModel && billingMode && providerPrice !== null) {
9667
- const unit = pricingModel === "per_page" ? "page" : pricingModel === "per_result" ? "result" : "call";
9668
- console.log(` Cost: ${formatDecimal(providerPrice)} provider credits per ${unit} (${billingMode})`);
9726
+ const summary = stringField(pricing, "summary");
9727
+ if (summary) {
9728
+ console.log(` Cost: ${summary}`);
9669
9729
  return true;
9670
9730
  }
9671
9731
  return false;
@@ -193,7 +193,7 @@ function resolveConfig(options) {
193
193
  }
194
194
 
195
195
  // src/version.ts
196
- var SDK_VERSION = "0.1.46";
196
+ var SDK_VERSION = "0.1.48";
197
197
  var SDK_API_CONTRACT = "2026-05-stripe-promo-checkout";
198
198
 
199
199
  // ../shared_libs/play-runtime/coordinator-headers.ts
@@ -2777,8 +2777,10 @@ async function handleCheckout(options) {
2777
2777
  }
2778
2778
  async function handleRedeemCode(code, options) {
2779
2779
  const { http } = getAuthedHttpClient();
2780
- const payload = await http.post("/api/v2/billing/checkout/verify", { code });
2781
- const url = String(payload.url || "");
2780
+ const payload = await http.post("/api/v2/billing/checkout", {
2781
+ discountCode: code
2782
+ });
2783
+ const url = String(payload.url || payload.checkout_url || "");
2782
2784
  if (!options.json && !options.noOpen && url) openInBrowser(url);
2783
2785
  printCommandEnvelope({
2784
2786
  ...payload,
@@ -9219,11 +9221,16 @@ function extractSummaryFields(payload) {
9219
9221
  }
9220
9222
 
9221
9223
  // src/cli/commands/tools.ts
9224
+ var TOOL_COMMAND_TEMPLATES = {
9225
+ describe: "deepline tools describe <toolId>",
9226
+ execute: "deepline tools execute <toolId> --input '{...}'"
9227
+ };
9222
9228
  function toListedTool(tool) {
9223
9229
  if (isPlayLikeTool(tool)) {
9224
9230
  const playReference = playReferenceForTool(tool);
9225
9231
  return {
9226
9232
  ...tool,
9233
+ description: listedToolDescription(tool),
9227
9234
  id: tool.toolId,
9228
9235
  type: "play",
9229
9236
  executeCommand: `deepline plays run ${playReference} --input '{...}' --watch`
@@ -9231,6 +9238,7 @@ function toListedTool(tool) {
9231
9238
  }
9232
9239
  return {
9233
9240
  ...tool,
9241
+ description: listedToolDescription(tool),
9234
9242
  id: tool.toolId,
9235
9243
  type: "tool",
9236
9244
  executeCommand: `deepline tools execute ${tool.toolId}`
@@ -9243,14 +9251,29 @@ async function listTools(args) {
9243
9251
  sections: [
9244
9252
  {
9245
9253
  title: `${items.length} tools available:`,
9246
- lines: items.flatMap((item) => {
9254
+ lines: items.map((item) => {
9247
9255
  const cats = item.categories.length ? ` [${item.categories.join(", ")}]` : "";
9248
- return [`${item.toolId}${cats}`, ` ${item.description}`];
9256
+ const pricing = formatListedToolCost(item);
9257
+ return `${item.toolId}${cats} - ${item.description}${pricing ? ` - ${pricing}` : ""}`;
9249
9258
  })
9259
+ },
9260
+ {
9261
+ title: "next",
9262
+ lines: [
9263
+ "Run `deepline tools describe <toolId>` before executing a tool."
9264
+ ]
9250
9265
  }
9251
9266
  ]
9252
9267
  };
9253
- printCommandEnvelope({ tools: items, count: items.length, render }, { json: argsWantJson(args) });
9268
+ printCommandEnvelope(
9269
+ {
9270
+ tools: items,
9271
+ count: items.length,
9272
+ commandTemplates: TOOL_COMMAND_TEMPLATES,
9273
+ render
9274
+ },
9275
+ { json: argsWantJson(args) }
9276
+ );
9254
9277
  return 0;
9255
9278
  }
9256
9279
  async function searchTools(queryInput, options = {}) {
@@ -9468,8 +9491,22 @@ async function getTool(args) {
9468
9491
  }
9469
9492
  function toolMetadataJsonForDescribe(tool, requestedToolId) {
9470
9493
  const toolId = String(tool.toolId || requestedToolId);
9494
+ const {
9495
+ cost: _cost,
9496
+ deeplineCreditsPerPricingUnit: _deeplineCreditsPerPricingUnit,
9497
+ deeplineUsdPerPricingUnit: _deeplineUsdPerPricingUnit,
9498
+ deeplineUsdPerCredit: _deeplineUsdPerCredit,
9499
+ deeplinePricingSummary: _deeplinePricingSummary,
9500
+ deeplinePricingDetails: _deeplinePricingDetails,
9501
+ deepline_credits_per_pricing_unit: _snakeDeeplineCreditsPerPricingUnit,
9502
+ deepline_usd_per_pricing_unit: _snakeDeeplineUsdPerPricingUnit,
9503
+ deepline_usd_per_credit: _snakeDeeplineUsdPerCredit,
9504
+ deepline_pricing_summary: _snakeDeeplinePricingSummary,
9505
+ deepline_pricing_details: _snakeDeeplinePricingDetails,
9506
+ ...publicTool
9507
+ } = tool;
9471
9508
  return {
9472
- ...tool,
9509
+ ...publicTool,
9473
9510
  toolId,
9474
9511
  provider: tool.provider,
9475
9512
  displayName: tool.displayName,
@@ -9488,9 +9525,9 @@ function printToolDetails(tool, requestedToolId) {
9488
9525
  const displayBase = operation && operation.startsWith(`${tool.provider}_`) ? operation.slice(String(tool.provider).length + 1) : operation ? `${tool.provider} ${operation}`.trim() : toolId;
9489
9526
  const displayName = titleCase(displayBase || String(tool.displayName || toolId));
9490
9527
  const cost = isRecord4(tool.cost) ? tool.cost : null;
9528
+ const pricing = recordField(tool, "pricing");
9491
9529
  const deeplineCredits = numberField(tool, "deeplineCreditsPerPricingUnit", "deepline_credits_per_pricing_unit");
9492
9530
  const deeplineUsdPerPricingUnit = numberField(tool, "deeplineUsdPerPricingUnit", "deepline_usd_per_pricing_unit");
9493
- const deeplineUsdPerCredit = numberField(tool, "deeplineUsdPerCredit", "deepline_usd_per_credit");
9494
9531
  const billingSource = stringField(tool, "billingSource", "billing_source");
9495
9532
  const billingSourceLabel = stringField(tool, "billingSourceLabel", "billing_source_label");
9496
9533
  const estimatedCreditsRange = stringField(tool, "estimatedCreditsRange", "estimated_credits_range");
@@ -9515,6 +9552,7 @@ function printToolDetails(tool, requestedToolId) {
9515
9552
  console.log(` ${tool.categories.join(", ")}`);
9516
9553
  }
9517
9554
  const printedCost = printToolCost({
9555
+ pricing,
9518
9556
  cost,
9519
9557
  billingSource,
9520
9558
  deeplineCredits,
@@ -9526,9 +9564,6 @@ function printToolDetails(tool, requestedToolId) {
9526
9564
  if (billingSourceLabel) {
9527
9565
  console.log(` Billing source: ${billingSourceLabel}`);
9528
9566
  }
9529
- if (typeof deeplineUsdPerCredit === "number") {
9530
- console.log(` Deepline rate: $${deeplineUsdPerCredit.toFixed(2)} per credit`);
9531
- }
9532
9567
  if (estimatedCreditsRange) {
9533
9568
  const usdSuffix = estimatedUsdRange ? ` (~${estimatedUsdRange})` : "";
9534
9569
  console.log(` Estimated play spend: ${estimatedCreditsRange}${usdSuffix}`);
@@ -9630,29 +9665,54 @@ function printExtractions(label, entries) {
9630
9665
  console.log(` - ${name}: ${expression}${pathSuffix}`);
9631
9666
  }
9632
9667
  }
9668
+ function singleLineText(value, maxLength = 260) {
9669
+ if (typeof value !== "string") return "";
9670
+ const text = value.replace(/\s+/g, " ").trim();
9671
+ if (text.length <= maxLength) return text;
9672
+ return `${text.slice(0, maxLength - 3).trimEnd()}...`;
9673
+ }
9674
+ function listedToolDescription(tool) {
9675
+ const record = tool;
9676
+ return singleLineText(record.bestFor ?? record.best_for ?? tool.description);
9677
+ }
9678
+ function formatListedToolCost(tool) {
9679
+ const record = tool;
9680
+ const pricing = recordField(record, "pricing");
9681
+ const displayText = stringField(pricing, "displayText", "display_text");
9682
+ return displayText ? `Cost: ${displayText}` : "";
9683
+ }
9633
9684
  function printToolCost(input) {
9634
- const { cost, billingSource, deeplineCredits, deeplineUsdPerPricingUnit } = input;
9635
- if (!cost) return false;
9636
- const pricingModel = typeof cost.pricingModel === "string" ? cost.pricingModel : typeof cost.pricing_model === "string" ? cost.pricing_model : "";
9637
- const billingMode = typeof cost.billingMode === "string" ? cost.billingMode : typeof cost.billing_mode === "string" ? cost.billing_mode : "";
9638
- const providerPrice = typeof cost.providerPricePerPricingModel === "number" ? cost.providerPricePerPricingModel : null;
9639
- if (pricingModel === "fixed" && providerPrice === 0) {
9640
- console.log(" Cost: free");
9641
- return true;
9642
- }
9685
+ const { pricing, cost, billingSource, deeplineCredits, deeplineUsdPerPricingUnit } = input;
9643
9686
  if (billingSource === "own_provider_credentials") {
9644
9687
  console.log(" Cost: free through Deepline");
9645
9688
  return true;
9646
9689
  }
9647
- if (pricingModel && billingMode && deeplineCredits !== null) {
9690
+ const displayText = stringField(pricing, "displayText", "display_text");
9691
+ if (displayText) {
9692
+ console.log(` Cost: ${displayText}`);
9693
+ const details = arrayField(pricing, "details").map((item) => String(item).trim()).filter(Boolean);
9694
+ if (details.length) {
9695
+ console.log(" notes:");
9696
+ for (const detail of details) console.log(` - ${detail}`);
9697
+ }
9698
+ return true;
9699
+ }
9700
+ const pricingModel = cost ? typeof cost.pricingModel === "string" ? cost.pricingModel : typeof cost.pricing_model === "string" ? cost.pricing_model : "" : "";
9701
+ const billingMode = cost ? typeof cost.billingMode === "string" ? cost.billingMode : typeof cost.billing_mode === "string" ? cost.billing_mode : "" : "";
9702
+ if (deeplineCredits === 0) {
9703
+ console.log(" Cost: Free");
9704
+ return true;
9705
+ }
9706
+ if (pricingModel && deeplineCredits !== null) {
9648
9707
  const unit = pricingModel === "per_page" ? "page" : pricingModel === "per_result" ? "result" : "call";
9649
9708
  const usdText = deeplineUsdPerPricingUnit !== null ? ` / ${formatUsd(deeplineUsdPerPricingUnit)}` : "";
9650
- console.log(` Cost: ${formatDecimal(deeplineCredits)} Deepline credits${usdText} per ${unit} (${billingMode})`);
9709
+ const billingSuffix = billingMode ? ` (${billingMode})` : "";
9710
+ console.log(` Cost: ${formatDecimal(deeplineCredits)} Deepline credits${usdText} per ${unit}${billingSuffix}`);
9651
9711
  return true;
9652
9712
  }
9653
- if (pricingModel && billingMode && providerPrice !== null) {
9654
- const unit = pricingModel === "per_page" ? "page" : pricingModel === "per_result" ? "result" : "call";
9655
- console.log(` Cost: ${formatDecimal(providerPrice)} provider credits per ${unit} (${billingMode})`);
9713
+ const summary = stringField(pricing, "summary");
9714
+ if (summary) {
9715
+ console.log(` Cost: ${summary}`);
9656
9716
  return true;
9657
9717
  }
9658
9718
  return false;
package/dist/index.d.mts CHANGED
@@ -221,6 +221,22 @@ interface CustomerDbQueryResult {
221
221
  columns: CustomerDbColumn[];
222
222
  rows: unknown[];
223
223
  }
224
+ interface ToolPricingSummary {
225
+ /** User-facing pricing text for quick discovery displays. */
226
+ displayText: string | null;
227
+ /** User-facing unit the price applies to. */
228
+ unit: 'call' | 'result' | 'page' | 'usage' | null;
229
+ /** Deepline credits charged per unit, when statically knowable. */
230
+ creditsPerUnit: number | null;
231
+ /** USD equivalent charged per unit, when statically knowable. */
232
+ usdPerUnit: number | null;
233
+ /** Currency for `usdPerUnit`. */
234
+ currency: 'USD';
235
+ /** Short user-facing pricing summary for variable pricing. */
236
+ summary: string | null;
237
+ /** Additional user-facing pricing notes. */
238
+ details: string[];
239
+ }
224
240
  /**
225
241
  * Summary definition of a tool, returned by {@link DeeplineClient.listTools}.
226
242
  *
@@ -255,6 +271,8 @@ interface ToolDefinition {
255
271
  inputSchema?: Record<string, unknown>;
256
272
  /** JSON Schema describing the tool's output shape. */
257
273
  outputSchema?: Record<string, unknown>;
274
+ /** User-facing pricing summary. Internal provider/settlement costs are intentionally omitted. */
275
+ pricing?: ToolPricingSummary | null;
258
276
  /** Copyable play-runtime guidance for V2 tool execution results. */
259
277
  usageGuidance?: {
260
278
  execute?: string;
@@ -327,6 +345,10 @@ interface ToolSearchResult {
327
345
  search_mode?: 'v1' | 'v2';
328
346
  search_fallback_to_category?: boolean;
329
347
  omitted_plays_hint?: string;
348
+ commandTemplates?: {
349
+ describe?: string;
350
+ execute?: string;
351
+ };
330
352
  render?: {
331
353
  sections?: Array<{
332
354
  title: string;
@@ -357,11 +379,11 @@ interface ToolMetadata extends ToolDefinition {
357
379
  asyncGetAction?: string | null;
358
380
  /** Known failure scenarios and their expected handling. */
359
381
  failureMode?: Record<string, unknown> | null;
360
- /** Provider-side pricing structure. */
382
+ /** Sanitized pricing model for describe metadata. Provider internal prices are intentionally omitted. */
361
383
  cost?: Record<string, unknown> | null;
362
- /** How many Deepline credits map to one provider pricing unit. */
384
+ /** Deepline credits charged for one user-visible pricing unit. */
363
385
  deeplineCreditsPerPricingUnit?: number | null;
364
- /** Whether cost is billed by the provider or by Deepline. */
386
+ /** Whether the customer pays with Deepline credits or their own connected account. */
365
387
  billingSource?: string;
366
388
  /** Display label for the billing source. */
367
389
  billingSourceLabel?: string;
@@ -1511,7 +1533,7 @@ declare class DeeplineClient {
1511
1533
  }>;
1512
1534
  }
1513
1535
 
1514
- declare const SDK_VERSION = "0.1.46";
1536
+ declare const SDK_VERSION = "0.1.48";
1515
1537
  declare const SDK_API_CONTRACT = "2026-05-stripe-promo-checkout";
1516
1538
 
1517
1539
  /**
@@ -1829,6 +1851,7 @@ type ToolExecutionRequest = {
1829
1851
  tool: string;
1830
1852
  input: Record<string, unknown>;
1831
1853
  description?: string;
1854
+ staleAfterSeconds?: number;
1832
1855
  };
1833
1856
  type StepResolver<Row, Value> = (row: Row, ctx: DeeplinePlayRuntimeContext, index: number) => Value | Promise<Value>;
1834
1857
  type ConditionalStepResolver<Row, Value, Else = null> = {
@@ -1912,7 +1935,10 @@ type CsvOptions = {
1912
1935
  * const enriched = await ctx
1913
1936
  * .map('companies', [{ domain: 'a.com' }, { domain: 'b.com' }])
1914
1937
  * .step('company', (row, rowCtx) =>
1915
- * rowCtx.tool('company_search', 'test_company_search', { domain: row.domain }, {
1938
+ * rowCtx.tools.execute({
1939
+ * id: 'company_search',
1940
+ * tool: 'test_company_search',
1941
+ * input: { domain: row.domain },
1916
1942
  * description: 'Look up company details by domain.',
1917
1943
  * }))
1918
1944
  * .run({ description: 'Look up company details.' });
@@ -1973,30 +1999,30 @@ interface DeeplinePlayRuntimeContext {
1973
1999
  *
1974
2000
  * @example Single tool per row
1975
2001
  * ```typescript
1976
- * const results = await ctx
1977
- * .map('companies', leads)
1978
- * .step('company', (row, ctx) =>
1979
- * ctx.tools.execute({
1980
- * id: 'company_search',
1981
- * tool: 'test_company_search',
1982
- * input: { domain: row.domain },
1983
- * description: 'Look up company details by domain.',
1984
- * }))
2002
+ * const results = await ctx
2003
+ * .map('companies', leads)
2004
+ * .step('company', (row, ctx) =>
2005
+ * ctx.tools.execute({
2006
+ * id: 'company_search',
2007
+ * tool: 'test_company_search',
2008
+ * input: { domain: row.domain },
2009
+ * description: 'Look up company details by domain.',
2010
+ * }))
1985
2011
  * .run({ description: 'Look up companies.' });
1986
2012
  * // [{ domain: 'stripe.com', company: { name: 'Stripe', ... } }, ...]
1987
2013
  * ```
1988
2014
  *
1989
2015
  * @example Multiple columns with pre/post logic
1990
2016
  * ```typescript
1991
- * const results = await ctx
1992
- * .map('leads', leads)
1993
- * .step('company', (row, ctx) =>
1994
- * ctx.tools.execute({
1995
- * id: 'company_search',
1996
- * tool: 'test_company_search',
1997
- * input: { domain: row.domain },
1998
- * description: 'Look up company details by domain.',
1999
- * }))
2017
+ * const results = await ctx
2018
+ * .map('leads', leads)
2019
+ * .step('company', (row, ctx) =>
2020
+ * ctx.tools.execute({
2021
+ * id: 'company_search',
2022
+ * tool: 'test_company_search',
2023
+ * input: { domain: row.domain },
2024
+ * description: 'Look up company details by domain.',
2025
+ * }))
2000
2026
  * .step('score', (row) =>
2001
2027
  * row.company?.employeeCount > 100 ? 'enterprise' : 'smb')
2002
2028
  * .run({ description: 'Enrich leads.' });
@@ -2013,22 +2039,19 @@ interface DeeplinePlayRuntimeContext {
2013
2039
  * @param request.input - Tool-specific input parameters
2014
2040
  * @returns The tool's output
2015
2041
  */
2016
- execute<TOutput = LoosePlayObject>(request: ToolExecutionRequest): Promise<ToolExecuteResult<TOutput>>;
2042
+ execute<TOutput = LoosePlayObject>(request: ToolExecutionRequest & {
2043
+ staleAfterSeconds?: number;
2044
+ }): Promise<ToolExecuteResult<TOutput>>;
2017
2045
  };
2018
- /**
2019
- * Execute a single tool by stable step key and tool ID.
2020
- *
2021
- * Shorthand for `ctx.tools.execute(...)`; this is the preferred spelling in
2022
- * row-level step programs.
2023
- */
2024
- tool<TOutput = LoosePlayObject>(key: string, toolId: string, input: Record<string, unknown>, options?: {
2025
- description?: string;
2026
- }): Promise<ToolExecuteResult<TOutput>>;
2027
2046
  runSteps<TInput extends Record<string, unknown>, TOutput>(program: StepProgram<TInput, any, TOutput>, input: TInput, options?: {
2028
2047
  description?: string;
2029
2048
  }): Promise<TOutput>;
2030
- step<T>(id: string, run: () => T | Promise<T>): Promise<T>;
2031
- fetch(key: string, url: string | URL, init?: RequestInit): Promise<{
2049
+ step<T>(id: string, run: () => T | Promise<T>, options?: {
2050
+ staleAfterSeconds?: number;
2051
+ }): Promise<T>;
2052
+ fetch(key: string, url: string | URL, init?: RequestInit, options?: {
2053
+ staleAfterSeconds?: number;
2054
+ }): Promise<{
2032
2055
  ok: boolean;
2033
2056
  status: number;
2034
2057
  statusText: string;
@@ -2039,6 +2062,7 @@ interface DeeplinePlayRuntimeContext {
2039
2062
  }>;
2040
2063
  runPlay(key: string, playRef: string | PlayReferenceLike, input: Record<string, unknown>, options: {
2041
2064
  description?: string;
2065
+ staleAfterSeconds?: number;
2042
2066
  }): Promise<Record<string, unknown>>;
2043
2067
  /**
2044
2068
  * Emit a log line visible in `play tail` and the play's progress logs.