deepline 0.3.294 → 0.3.295

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 (136) hide show
  1. package/dist/bundling-sources/sdk/src/compat.ts +35 -7
  2. package/dist/bundling-sources/sdk/src/release.ts +1 -1
  3. package/dist/bundling-sources/shared_libs/play-runtime/tool-http-errors.ts +14 -1
  4. package/dist/cli/auth-EDTRERZP.mjs +31 -0
  5. package/dist/cli/auth-TDHKB277.js +31 -0
  6. package/dist/cli/billing-ELIDPILY.js +1749 -0
  7. package/dist/cli/billing-EXGXJVAU.mjs +1749 -0
  8. package/dist/cli/chunk-2S5Y3TZP.js +5688 -0
  9. package/dist/cli/chunk-3KC45UVF.js +150 -0
  10. package/dist/cli/chunk-3XX5TEA4.js +15 -0
  11. package/dist/cli/chunk-4MBOJQPL.mjs +0 -0
  12. package/dist/cli/chunk-4NEFYBF7.js +2240 -0
  13. package/dist/cli/chunk-5JLQPVNX.js +3056 -0
  14. package/dist/cli/chunk-5KDKFHZI.js +1269 -0
  15. package/dist/cli/chunk-6A3TJUWC.js +76 -0
  16. package/dist/cli/chunk-6O5YZOVN.mjs +890 -0
  17. package/dist/cli/chunk-7P5AA3SN.js +344 -0
  18. package/dist/cli/chunk-AYHLUHE5.js +52 -0
  19. package/dist/cli/chunk-CBVIJSHF.mjs +560 -0
  20. package/dist/cli/chunk-CFVVCN4A.js +735 -0
  21. package/dist/cli/chunk-COGTRVWW.js +30 -0
  22. package/dist/cli/chunk-D4AZUZO4.js +190 -0
  23. package/dist/cli/chunk-DLIRSHV6.mjs +28 -0
  24. package/dist/cli/chunk-EACVZI6N.mjs +1995 -0
  25. package/dist/cli/chunk-EDWJY6T4.mjs +3056 -0
  26. package/dist/cli/chunk-EXMLR72R.mjs +0 -0
  27. package/dist/cli/chunk-F35VOIQL.js +890 -0
  28. package/dist/cli/chunk-GAMFK2ZP.mjs +148 -0
  29. package/dist/cli/chunk-GHRQQPW2.mjs +2240 -0
  30. package/dist/cli/chunk-GONRLVV3.js +3440 -0
  31. package/dist/cli/chunk-GVUJJJ5G.mjs +76 -0
  32. package/dist/cli/chunk-H7HIDGZ7.mjs +150 -0
  33. package/dist/cli/chunk-HUZXWOSK.mjs +503 -0
  34. package/dist/cli/chunk-I5YZLGMG.js +1 -0
  35. package/dist/cli/chunk-ITOFSXIU.mjs +15 -0
  36. package/dist/cli/chunk-J5NA2TTX.js +503 -0
  37. package/dist/cli/chunk-JCS5TPNY.mjs +3440 -0
  38. package/dist/cli/chunk-JNNOCMQY.js +47 -0
  39. package/dist/cli/chunk-KRD6H754.mjs +30 -0
  40. package/dist/cli/chunk-LA46MMTL.js +560 -0
  41. package/dist/cli/chunk-LDWT7RJK.mjs +190 -0
  42. package/dist/cli/chunk-M2V26OR5.js +499 -0
  43. package/dist/cli/chunk-MIMASXO4.mjs +389 -0
  44. package/dist/cli/chunk-MROPCKW2.mjs +190 -0
  45. package/dist/cli/chunk-NXDRDJ4K.js +389 -0
  46. package/dist/cli/chunk-NXGCO4JB.mjs +344 -0
  47. package/dist/cli/chunk-OG64RBAC.js +6 -0
  48. package/dist/cli/chunk-OQYEC4GL.mjs +34 -0
  49. package/dist/cli/chunk-OWJZUE3Y.mjs +103 -0
  50. package/dist/cli/chunk-SDK3ZA2C.js +103 -0
  51. package/dist/cli/chunk-SFLARO4Y.mjs +47 -0
  52. package/dist/cli/chunk-SVIIIYIQ.js +923 -0
  53. package/dist/cli/chunk-TAC3JIFE.mjs +354 -0
  54. package/dist/cli/chunk-U3PI7HBM.js +34 -0
  55. package/dist/cli/chunk-UFS752TU.mjs +52 -0
  56. package/dist/cli/chunk-UI37DQE7.mjs +499 -0
  57. package/dist/cli/chunk-UNEMDKXN.js +1 -0
  58. package/dist/cli/chunk-WB6Z2Q44.mjs +1622 -0
  59. package/dist/cli/chunk-WJYPBHTE.js +148 -0
  60. package/dist/cli/chunk-WOHBA5PV.js +354 -0
  61. package/dist/cli/chunk-WQICC2B3.js +190 -0
  62. package/dist/cli/chunk-WZYKRD7T.mjs +6 -0
  63. package/dist/cli/chunk-XL2FO6CW.mjs +5688 -0
  64. package/dist/cli/chunk-XNYIZMNQ.js +28 -0
  65. package/dist/cli/chunk-XRK2TZT5.js +1995 -0
  66. package/dist/cli/chunk-YJYPL5OK.mjs +1269 -0
  67. package/dist/cli/chunk-YWNDYCXR.mjs +735 -0
  68. package/dist/cli/chunk-YWWAF7KZ.mjs +923 -0
  69. package/dist/cli/chunk-ZDO3TO3M.js +1622 -0
  70. package/dist/cli/client-4JVOYVC5.js +20 -0
  71. package/dist/cli/client-EEN2IJN2.mjs +20 -0
  72. package/dist/cli/csv-BOHBEP2I.mjs +585 -0
  73. package/dist/cli/csv-S5NYRUEX.js +585 -0
  74. package/dist/cli/db-CLODWCOB.mjs +486 -0
  75. package/dist/cli/db-F6PKFOOV.js +486 -0
  76. package/dist/cli/executions-5TQAKLJU.js +28 -0
  77. package/dist/cli/executions-MAKW6QOY.mjs +28 -0
  78. package/dist/cli/feedback-GV4QJFEN.js +107 -0
  79. package/dist/cli/feedback-XY24TW7H.mjs +107 -0
  80. package/dist/cli/getting-started.js +18 -76
  81. package/dist/cli/getting-started.mjs +10 -37
  82. package/dist/cli/git-6S2C22T5.js +23 -0
  83. package/dist/cli/git-OZLBD5HH.mjs +23 -0
  84. package/dist/cli/index.js +291 -54294
  85. package/dist/cli/index.mjs +209 -54352
  86. package/dist/cli/legacy-noops-LLCGDPQE.js +157 -0
  87. package/dist/cli/legacy-noops-TYH3TW2D.mjs +157 -0
  88. package/dist/cli/monitors-CABMB4DW.js +3251 -0
  89. package/dist/cli/monitors-TTD55HMK.mjs +3251 -0
  90. package/dist/cli/org-MSF3RG76.js +849 -0
  91. package/dist/cli/org-SFJ77MWY.mjs +849 -0
  92. package/dist/cli/play-NXHJSCKL.mjs +18439 -0
  93. package/dist/cli/play-OKSFNNO4.js +18439 -0
  94. package/dist/cli/providers-QC2ERERL.js +95 -0
  95. package/dist/cli/providers-TIIAZEUA.mjs +95 -0
  96. package/dist/cli/proxy-env-EBANZHPV.js +161 -0
  97. package/dist/cli/proxy-env-M4ZHXHRL.mjs +161 -0
  98. package/dist/cli/quickstart-ICANHLMI.js +69 -0
  99. package/dist/cli/quickstart-KWUOP3FI.mjs +69 -0
  100. package/dist/cli/search-U5H2FDOO.mjs +18 -0
  101. package/dist/cli/search-XQRQOLWS.js +18 -0
  102. package/dist/cli/secrets-3J6YTWFA.mjs +400 -0
  103. package/dist/cli/secrets-YNMNZNOM.js +400 -0
  104. package/dist/cli/sessions-CLEES4L6.mjs +15 -0
  105. package/dist/cli/sessions-J6VR47FG.js +15 -0
  106. package/dist/cli/settings-EEKZMTY4.js +846 -0
  107. package/dist/cli/settings-UVLOQZRH.mjs +846 -0
  108. package/dist/cli/setup-DLMDXPGJ.mjs +1257 -0
  109. package/dist/cli/setup-HC4Q7QM4.js +1257 -0
  110. package/dist/cli/skills-33PHFBSB.mjs +28 -0
  111. package/dist/cli/skills-LFRY3KPX.js +28 -0
  112. package/dist/cli/tools-3COEPKML.mjs +2955 -0
  113. package/dist/cli/tools-QXEVCN45.js +2955 -0
  114. package/dist/cli/update-LSAC4FF5.mjs +28 -0
  115. package/dist/cli/update-NXHSPYXA.js +28 -0
  116. package/dist/cli/workflow-7S44OECF.mjs +1936 -0
  117. package/dist/cli/workflow-QPZWYSZE.js +1936 -0
  118. package/dist/helpers.js +6 -32
  119. package/dist/helpers.mjs +2 -0
  120. package/dist/index.js +1972 -12825
  121. package/dist/index.mjs +1910 -12672
  122. package/dist/install-integrity.json +110 -0
  123. package/dist/monitor-fleet-contract.js +31 -730
  124. package/dist/monitor-fleet-contract.mjs +18 -667
  125. package/dist/monitor-input-contract.js +10 -390
  126. package/dist/monitor-input-contract.mjs +7 -348
  127. package/dist/plays/bundle-play-file.mjs +13 -5178
  128. package/dist/plays/csv-data-input.js +5 -3132
  129. package/dist/plays/csv-data-input.mjs +5 -3105
  130. package/dist/plays/run-request.js +56 -664
  131. package/dist/plays/run-request.mjs +30 -588
  132. package/dist/release.d.mts +1 -1
  133. package/dist/release.d.ts +1 -1
  134. package/dist/release.js +5 -212
  135. package/dist/release.mjs +5 -185
  136. package/package.json +1 -1
@@ -0,0 +1,2955 @@
1
+ "use strict";Object.defineProperty(exports, "__esModule", {value: true}); function _nullishCoalesce(lhs, rhsFn) { if (lhs != null) { return lhs; } else { return rhsFn(); } } function _optionalChain(ops) { let lastAccessLHS = undefined; let value = ops[0]; let i = 1; while (i < ops.length) { const op = ops[i]; const fn = ops[i + 1]; i += 2; if ((op === 'optionalAccess' || op === 'optionalCall') && value == null) { return undefined; } if (op === 'access' || op === 'optionalAccess') { lastAccessLHS = value; value = fn(value); } else if (op === 'call' || op === 'optionalCall') { value = fn((...args) => value.call(lastAccessLHS, ...args)); lastAccessLHS = undefined; } } return value; }
2
+
3
+
4
+ var _chunkWQICC2B3js = require('./chunk-WQICC2B3.js');
5
+
6
+
7
+
8
+
9
+
10
+
11
+
12
+ var _chunkNXDRDJ4Kjs = require('./chunk-NXDRDJ4K.js');
13
+
14
+
15
+ var _chunk2S5Y3TZPjs = require('./chunk-2S5Y3TZP.js');
16
+ require('./chunk-LA46MMTL.js');
17
+
18
+
19
+
20
+
21
+
22
+
23
+
24
+
25
+ var _chunkF35VOIQLjs = require('./chunk-F35VOIQL.js');
26
+
27
+
28
+
29
+ var _chunkXRK2TZT5js = require('./chunk-XRK2TZT5.js');
30
+ require('./chunk-XNYIZMNQ.js');
31
+ require('./chunk-D4AZUZO4.js');
32
+ require('./chunk-6A3TJUWC.js');
33
+
34
+
35
+ var _chunk7P5AA3SNjs = require('./chunk-7P5AA3SN.js');
36
+ require('./chunk-OG64RBAC.js');
37
+ require('./chunk-COGTRVWW.js');
38
+
39
+ // src/cli/commands/tools.ts
40
+ var _commander = require('commander');
41
+
42
+
43
+
44
+
45
+
46
+
47
+ var _fs = require('fs');
48
+ var _os = require('os');
49
+ var _path = require('path');
50
+
51
+ // src/cli/tool-call-recovery.ts
52
+ var _crypto = require('crypto');
53
+
54
+
55
+
56
+
57
+
58
+
59
+
60
+
61
+
62
+ var ToolCallRecovery = class _ToolCallRecovery {
63
+ constructor(idempotencyKey, path) {
64
+ this.idempotencyKey = idempotencyKey;
65
+ this.path = path;
66
+ }
67
+ static open(input) {
68
+ if (!input.recover || input.idempotencyKey) {
69
+ return new _ToolCallRecovery(input.idempotencyKey, null);
70
+ }
71
+ const path = pendingToolExecutionPath(input);
72
+ return new _ToolCallRecovery(loadOrCreatePendingToolExecution(path), path);
73
+ }
74
+ async acknowledgeDelivery() {
75
+ await completePendingToolExecution(this.path, this.idempotencyKey);
76
+ }
77
+ };
78
+ function pendingToolExecutionPath(input) {
79
+ const config = _chunkXRK2TZT5js.resolveConfig.call(void 0, );
80
+ const fingerprint = _crypto.createHash.call(void 0, "sha256").update(config.baseUrl).update("\0").update(_crypto.createHash.call(void 0, "sha256").update(config.apiKey).digest("hex")).update("\0").update(input.toolId).update("\0").update(_chunkNXDRDJ4Kjs.stableStringify.call(void 0, input.params)).update("\0").update(input.responseIntent).digest("hex");
81
+ return _path.join.call(void 0,
82
+ _chunkXRK2TZT5js.sdkCliStateDirPath.call(void 0, config.baseUrl),
83
+ `pending-tool-execution-${fingerprint}.json`
84
+ );
85
+ }
86
+ function loadOrCreatePendingToolExecution(path) {
87
+ _fs.mkdirSync.call(void 0, _path.dirname.call(void 0, path), { recursive: true });
88
+ if (_fs.existsSync.call(void 0, path)) {
89
+ return readPendingToolExecution(path);
90
+ }
91
+ const idempotencyKey = _crypto.randomUUID.call(void 0, );
92
+ const temporaryPath = `${path}.${process.pid}.${_crypto.randomUUID.call(void 0, )}.tmp`;
93
+ try {
94
+ _fs.writeFileSync.call(void 0, temporaryPath, `${JSON.stringify({ idempotencyKey })}
95
+ `, {
96
+ encoding: "utf8",
97
+ flag: "wx",
98
+ mode: 384
99
+ });
100
+ _fs.linkSync.call(void 0, temporaryPath, path);
101
+ return idempotencyKey;
102
+ } catch (error) {
103
+ if (error.code !== "EEXIST") throw error;
104
+ return readPendingToolExecution(path);
105
+ } finally {
106
+ if (_fs.existsSync.call(void 0, temporaryPath)) _fs.unlinkSync.call(void 0, temporaryPath);
107
+ }
108
+ }
109
+ function readPendingToolExecution(path) {
110
+ const saved = JSON.parse(_fs.readFileSync.call(void 0, path, "utf8"));
111
+ if (typeof saved.idempotencyKey !== "string") {
112
+ throw new Error(
113
+ `Cannot resume the saved tool execution at ${path}: invalid recovery key.`
114
+ );
115
+ }
116
+ return saved.idempotencyKey;
117
+ }
118
+ async function completePendingToolExecution(path, idempotencyKey) {
119
+ if (!path || !idempotencyKey || !_fs.existsSync.call(void 0, path)) return;
120
+ await new Promise((resolve2, reject) => {
121
+ const onError = (error) => {
122
+ process.stdout.off("error", onError);
123
+ reject(error);
124
+ };
125
+ process.stdout.once("error", onError);
126
+ process.stdout.write("", (error) => {
127
+ process.stdout.off("error", onError);
128
+ if (error) {
129
+ reject(error);
130
+ } else {
131
+ resolve2();
132
+ }
133
+ });
134
+ });
135
+ try {
136
+ if (readPendingToolExecution(path) !== idempotencyKey) return;
137
+ _fs.unlinkSync.call(void 0, path);
138
+ } catch (error) {
139
+ if (error.code !== "ENOENT") throw error;
140
+ }
141
+ }
142
+
143
+ // ../plays/tool-category-descriptions.ts
144
+ var TOOL_CATEGORY_DESCRIPTIONS = {
145
+ company_search: "Find companies matching firmographic, ad, or web criteria.",
146
+ people_search: "Find people matching role, company, or persona criteria.",
147
+ people_enrich: "Enrich a known person with contact, social, and profile data.",
148
+ company_enrich: "Enrich a known company with firmographic and account data.",
149
+ email_finder: "Find work or personal email addresses for a person.",
150
+ email_verify: "Validate email deliverability and catch-all status.",
151
+ phone_finder: "Find mobile or direct phone numbers for a person.",
152
+ phone_verify: "Validate phone-number reachability and line type.",
153
+ research: "Research accounts, people, news, and signals for context and scoring.",
154
+ autocomplete: "Resolve names and entities to canonical catalog records.",
155
+ automation: "Kick off provider-side jobs, exports, and asynchronous workflows.",
156
+ outbound_tools: "Run outbound sequencing, deliverability, and campaign operations.",
157
+ admin: "Provider-side status, metadata, and account operations behind other tools.",
158
+ smb: "Look up small-business listings, local records, and public filings.",
159
+ identity_resolution: "Match a partial identity to a single resolved person or company.",
160
+ reverse_lookup: "Resolve an email, phone, or profile back to a person.",
161
+ enrichment: "General-purpose record enrichment across people and companies.",
162
+ batch: "Run an enrichment or search operation over many rows at once.",
163
+ premium: "Higher-cost tools with premium provider coverage.",
164
+ free: "Free tools that do not spend Deepline credits."
165
+ };
166
+ var WELL_KNOWN_TOOL_CATEGORIES = Object.freeze(
167
+ Object.keys(TOOL_CATEGORY_DESCRIPTIONS)
168
+ );
169
+ function describeToolCategory(category) {
170
+ return _nullishCoalesce(TOOL_CATEGORY_DESCRIPTIONS[category], () => ( null));
171
+ }
172
+
173
+ // src/cli/commands/model-description.ts
174
+ function formatModelDescription(description) {
175
+ const lines = [];
176
+ lines.push(description.model);
177
+ lines.push(`Provider: ${description.provider}`);
178
+ const name = stringField(description.modelMetadata, "name");
179
+ if (name) lines.push(`Name: ${name}`);
180
+ const contextWindow = numberField(
181
+ description.modelMetadata,
182
+ "context_window"
183
+ );
184
+ if (contextWindow !== null) lines.push(`Context: ${contextWindow}`);
185
+ const tags = arrayField(description.modelMetadata, "tags").filter(
186
+ (value) => typeof value === "string"
187
+ );
188
+ if (tags.length) lines.push(`Tags: ${tags.join(", ")}`);
189
+ lines.push("");
190
+ lines.push("Provider options:");
191
+ appendNamespace(lines, description.providerOptions.gateway);
192
+ if (description.providerOptions.selectedProvider) {
193
+ appendNamespace(lines, description.providerOptions.selectedProvider);
194
+ }
195
+ lines.push("");
196
+ lines.push("Example input:");
197
+ lines.push(JSON.stringify(description.exampleInput, null, 2));
198
+ if (description.caveats.length) {
199
+ lines.push("");
200
+ lines.push("Caveats:");
201
+ for (const caveat of description.caveats) {
202
+ lines.push(`- ${caveat}`);
203
+ }
204
+ }
205
+ return `${lines.join("\n")}
206
+ `;
207
+ }
208
+ function appendNamespace(lines, namespace) {
209
+ lines.push(`- ${namespace.provider} (${namespace.sourceSymbol})`);
210
+ for (const field of namespace.fields) {
211
+ const values = _optionalChain([field, 'access', _ => _.enumValues, 'optionalAccess', _2 => _2.length]) ? ` (${field.enumValues.map((value) => JSON.stringify(value)).join(" | ")})` : "";
212
+ lines.push(
213
+ ` - ${field.name}: ${field.type}${values} - ${field.description}`
214
+ );
215
+ }
216
+ }
217
+ function stringField(value, key) {
218
+ if (!value || typeof value !== "object" || Array.isArray(value)) return null;
219
+ const candidate = value[key];
220
+ return typeof candidate === "string" && candidate.trim() ? candidate.trim() : null;
221
+ }
222
+ function numberField(value, key) {
223
+ if (!value || typeof value !== "object" || Array.isArray(value)) return null;
224
+ const candidate = value[key];
225
+ return typeof candidate === "number" ? candidate : null;
226
+ }
227
+ function arrayField(value, key) {
228
+ if (!value || typeof value !== "object" || Array.isArray(value)) return [];
229
+ const candidate = value[key];
230
+ return Array.isArray(candidate) ? candidate : [];
231
+ }
232
+
233
+ // src/cli/tool-description.ts
234
+ var Capability = class _Capability {
235
+ #catalogEntry;
236
+ constructor(catalogEntry) {
237
+ this.#catalogEntry = catalogEntry;
238
+ }
239
+ static fromCatalogEntry(catalogEntry) {
240
+ return new _Capability(catalogEntry);
241
+ }
242
+ describe() {
243
+ return CapabilityDescription.fromCatalogEntry(this.#catalogEntry);
244
+ }
245
+ };
246
+ var CapabilityDescription = class _CapabilityDescription {
247
+ #catalogEntry;
248
+ constructor(catalogEntry) {
249
+ this.#catalogEntry = catalogEntry;
250
+ }
251
+ static fromCatalogEntry(catalogEntry) {
252
+ return new _CapabilityDescription(catalogEntry);
253
+ }
254
+ /**
255
+ * The customer price already resolved by the catalog. This intentionally
256
+ * omits provider-price fields, even when a catalog Adapter carried them.
257
+ */
258
+ customerCost() {
259
+ const legacyCost = recordValue(this.#catalogEntry.cost);
260
+ const pricing = recordValue(this.#catalogEntry.pricing);
261
+ const unit = stringValue(pricing.unit);
262
+ const legacyPricingModel = stringValue(
263
+ _nullishCoalesce(legacyCost.pricingModel, () => ( legacyCost.pricing_model))
264
+ );
265
+ const pricingModel = unit === "call" ? "fixed" : unit === "result" || unit === "page" ? `per_${unit}` : unit === "usage" ? "provider_usage" : legacyPricingModel;
266
+ const canonicalCredits = pricingNumber(
267
+ pricing,
268
+ "creditsPerUnit",
269
+ "credits_per_unit",
270
+ _nullishCoalesce(this.#catalogEntry.deeplineCreditsPerPricingUnit, () => ( this.#catalogEntry.deepline_credits_per_pricing_unit))
271
+ );
272
+ const canonicalUsd = pricingNumber(
273
+ pricing,
274
+ "usdPerUnit",
275
+ "usd_per_unit",
276
+ _nullishCoalesce(this.#catalogEntry.deeplineUsdPerPricingUnit, () => ( this.#catalogEntry.deepline_usd_per_pricing_unit))
277
+ );
278
+ const billingSource = stringValue(
279
+ _nullishCoalesce(this.#catalogEntry.billingSource, () => ( this.#catalogEntry.billing_source))
280
+ );
281
+ const billingSourceLabel = stringValue(
282
+ _nullishCoalesce(this.#catalogEntry.billingSourceLabel, () => ( this.#catalogEntry.billing_source_label))
283
+ );
284
+ const isFree = billingSource === "free";
285
+ return {
286
+ pricingModel: pricingModel || null,
287
+ unit: unit || null,
288
+ displayText: isFree ? "Free" : stringValue(_nullishCoalesce(pricing.displayText, () => ( pricing.display_text))),
289
+ summary: isFree ? null : stringValue(pricing.summary),
290
+ billingMode: stringValue(
291
+ _nullishCoalesce(legacyCost.billingMode, () => ( legacyCost.billing_mode))
292
+ ),
293
+ billingSource,
294
+ billingSourceLabel,
295
+ deeplineCreditsPerPricingUnit: isFree ? 0 : canonicalCredits,
296
+ deeplineUsdPerPricingUnit: isFree ? 0 : canonicalUsd
297
+ };
298
+ }
299
+ };
300
+ function recordValue(value) {
301
+ return value && typeof value === "object" && !Array.isArray(value) ? value : {};
302
+ }
303
+ function stringValue(value) {
304
+ return typeof value === "string" && value.trim() ? value : null;
305
+ }
306
+ function numberValue(value) {
307
+ return typeof value === "number" && Number.isFinite(value) ? value : null;
308
+ }
309
+ function pricingNumber(pricing, canonicalKey, aliasKey, legacyValue) {
310
+ for (const key of [canonicalKey, aliasKey]) {
311
+ if (Object.prototype.hasOwnProperty.call(pricing, key))
312
+ return numberValue(pricing[key]);
313
+ }
314
+ return numberValue(legacyValue);
315
+ }
316
+
317
+ // src/cli/tool-connection-status.ts
318
+ function toolConnectionStatusMessage(input) {
319
+ if (input.credentialStatus === "requires_connection") {
320
+ return "requires your credentials \u2014 not connected (connect to use)";
321
+ }
322
+ if (input.connected === false && input.credentialStatus === "managed") {
323
+ return "temporarily unavailable";
324
+ }
325
+ return null;
326
+ }
327
+
328
+ // src/cli/commands/tools.ts
329
+ var TOOL_COMMAND_TEMPLATES = {
330
+ describe: "deepline tools describe <toolId>",
331
+ execute: "deepline tools execute <toolId> --input '{...}'"
332
+ };
333
+ function toListedTool(tool) {
334
+ if (isPlayLikeTool(tool)) {
335
+ return {
336
+ ...tool,
337
+ description: listedToolDescription(tool),
338
+ id: tool.toolId,
339
+ type: "play",
340
+ executeCommand: playRunCommandForTool(tool, tool.toolId)
341
+ };
342
+ }
343
+ return {
344
+ ...tool,
345
+ description: listedToolDescription(tool),
346
+ id: tool.toolId,
347
+ type: "tool",
348
+ executeCommand: `deepline tools execute ${tool.toolId}`
349
+ };
350
+ }
351
+ function normalizeGrepText(value) {
352
+ if (value === null || value === void 0) return "";
353
+ if (typeof value === "string") return value.toLowerCase();
354
+ if (typeof value === "number" || typeof value === "boolean") {
355
+ return String(value).toLowerCase();
356
+ }
357
+ if (Array.isArray(value)) return value.map(normalizeGrepText).join(" ");
358
+ if (typeof value === "object") {
359
+ return Object.values(value).map(normalizeGrepText).join(" ");
360
+ }
361
+ return "";
362
+ }
363
+ function parseGrepTerms(query, mode) {
364
+ const trimmed = query.trim().toLowerCase();
365
+ if (!trimmed) return [];
366
+ if (mode === "phrase") return [trimmed];
367
+ const matches = _nullishCoalesce(trimmed.match(/"([^"]+)"|'([^']+)'|\S+/g), () => ( []));
368
+ return matches.map((term) => term.replace(/^["']|["']$/g, "").trim()).filter(Boolean);
369
+ }
370
+ function matchesGrepQuery(value, query, mode) {
371
+ const terms = parseGrepTerms(query, mode);
372
+ if (terms.length === 0) return true;
373
+ const haystack = normalizeGrepText(value);
374
+ if (mode === "any") return terms.some((term) => haystack.includes(term));
375
+ return terms.every((term) => haystack.includes(term));
376
+ }
377
+ function shellCommandArg(value) {
378
+ return `'${value.replace(/'/g, `'\\''`)}'`;
379
+ }
380
+ function zeroMatchToolGuidance(options) {
381
+ const categories = _nullishCoalesce(options.categories, () => ( []));
382
+ const query = _nullishCoalesce(_optionalChain([options, 'access', _3 => _3.query, 'optionalAccess', _4 => _4.trim, 'call', _5 => _5()]), () => ( ""));
383
+ const filterText = [
384
+ categories.length ? `categories=${categories.join(",")}` : null,
385
+ query ? `grep=${query}` : null,
386
+ query ? `grep_mode=${_nullishCoalesce(options.mode, () => ( "all"))}` : null
387
+ ].filter(Boolean).join(" ");
388
+ const suggestions = [
389
+ ...query ? [
390
+ {
391
+ label: "Use ranked semantic search for intent-style queries",
392
+ command: `deepline search --type tools -- ${shellCommandArg(query)}`
393
+ },
394
+ ...options.mode === "all" ? [
395
+ {
396
+ label: "Relax literal grep from AND to OR matching",
397
+ command: `deepline tools grep --mode any -- ${shellCommandArg(query)}`
398
+ }
399
+ ] : []
400
+ ] : [],
401
+ {
402
+ label: "List the current atomic tool catalog",
403
+ command: "deepline tools list --json"
404
+ },
405
+ ...query ? [
406
+ {
407
+ label: "Search composed Deepline plays separately",
408
+ command: `deepline search --type prebuilts -- ${shellCommandArg(query)}`
409
+ }
410
+ ] : []
411
+ ];
412
+ return {
413
+ reason: "filters_matched_no_atomic_tools",
414
+ message: `The tools catalog responded successfully, but no atomic provider tools matched ${filterText || "the current filters"}. This is a zero-match filter result, not a registry outage.`,
415
+ suggestions
416
+ };
417
+ }
418
+ function zeroMatchRender(emptyResult) {
419
+ return {
420
+ sections: [
421
+ {
422
+ title: "0 tools available:",
423
+ lines: [emptyResult.message]
424
+ },
425
+ {
426
+ title: "suggestions",
427
+ lines: emptyResult.suggestions.map(
428
+ (suggestion) => `${suggestion.label}: ${suggestion.command}`
429
+ )
430
+ }
431
+ ]
432
+ };
433
+ }
434
+ function firstSentence(text) {
435
+ const clean = (_nullishCoalesce(text, () => ( ""))).replace(/\s+/g, " ").trim();
436
+ if (!clean) return "";
437
+ const match = clean.match(/^.*?[.!?](?=\s|$)/);
438
+ return (match ? match[0] : clean).trim();
439
+ }
440
+ function requiredInputIds(tool) {
441
+ const inputSchema = recordField(
442
+ tool,
443
+ "inputSchema",
444
+ "input_schema"
445
+ );
446
+ return toolInputFieldsForDisplay(inputSchema).filter((field) => field.required === true).map((field) => String(_nullishCoalesce(field.name, () => ( "")))).filter(Boolean);
447
+ }
448
+ function notConnectedSuffix(tool) {
449
+ const record = tool;
450
+ const status = stringField2(record, "credentialStatus", "credential_status");
451
+ const connected = record.connected;
452
+ const message = toolConnectionStatusMessage({
453
+ connected: connected === false ? false : void 0,
454
+ credentialStatus: status || void 0
455
+ });
456
+ return message ? ` - \u26A0 ${message}` : "";
457
+ }
458
+ function shortPricingHint(tool) {
459
+ const pricing = recordField(
460
+ tool,
461
+ "pricing"
462
+ );
463
+ const credits = numberField2(pricing, "creditsPerUnit", "credits_per_unit");
464
+ const unit = stringField2(pricing, "unit");
465
+ if (credits !== null) {
466
+ return `${formatDecimal(credits)} cr/${unit || "unit"}`;
467
+ }
468
+ const summary = stringField2(pricing, "summary");
469
+ if (summary) return summary;
470
+ const displayText = stringField2(pricing, "displayText", "display_text");
471
+ return displayText || null;
472
+ }
473
+ function aggregateCategorySummaries(tools) {
474
+ const counts = /* @__PURE__ */ new Map();
475
+ for (const tool of tools) {
476
+ for (const category of _nullishCoalesce(tool.categories, () => ( []))) {
477
+ counts.set(category, (_nullishCoalesce(counts.get(category), () => ( 0))) + 1);
478
+ }
479
+ }
480
+ return [...counts.entries()].map(([name, count]) => ({
481
+ name,
482
+ count,
483
+ description: describeToolCategory(name)
484
+ })).sort((a, b) => b.count - a.count || a.name.localeCompare(b.name));
485
+ }
486
+ function categoryEnumerationRender(summaries) {
487
+ const nameWidth = summaries.reduce(
488
+ (max, item) => Math.max(max, item.name.length),
489
+ 0
490
+ );
491
+ const countWidth = summaries.reduce(
492
+ (max, item) => Math.max(max, String(item.count).length),
493
+ 0
494
+ );
495
+ return {
496
+ sections: [
497
+ {
498
+ title: `${summaries.length} tool categories:`,
499
+ lines: summaries.map((item) => {
500
+ const name = item.name.padEnd(nameWidth);
501
+ const count = String(item.count).padStart(countWidth);
502
+ const definition = item.description ? ` - ${item.description}` : "";
503
+ return `${name} ${count}${definition}`;
504
+ })
505
+ },
506
+ {
507
+ title: "next",
508
+ lines: ["Pass a category: deepline tools list email_finder"]
509
+ }
510
+ ]
511
+ };
512
+ }
513
+ async function listToolCategories(emitJson, compact) {
514
+ const client = new (0, _chunk2S5Y3TZPjs.DeeplineClient)();
515
+ const rawTools = await client.listTools({ compact });
516
+ const items = rawTools.map(toListedTool);
517
+ const summaries = aggregateCategorySummaries(rawTools);
518
+ const outputItems = compact ? items.map(compactTool) : items;
519
+ _chunkF35VOIQLjs.printCommandEnvelope.call(void 0,
520
+ {
521
+ tools: outputItems,
522
+ count: outputItems.length,
523
+ categories: summaries,
524
+ filters: {
525
+ categories: []
526
+ },
527
+ commandTemplates: TOOL_COMMAND_TEMPLATES,
528
+ render: categoryEnumerationRender(summaries)
529
+ },
530
+ { json: emitJson }
531
+ );
532
+ return 0;
533
+ }
534
+ function unknownCategoryError(category, summaries, emitJson) {
535
+ const known = summaries.map((item) => item.name);
536
+ const message = `Unknown tool category "${category}". Run \`deepline tools list\` to browse categories.`;
537
+ if (emitJson) {
538
+ _chunkF35VOIQLjs.printJson.call(void 0, {
539
+ ok: false,
540
+ exitCode: 4,
541
+ code: "TOOL_CATEGORY_NOT_FOUND",
542
+ message,
543
+ category,
544
+ categories: summaries,
545
+ next: "deepline tools list"
546
+ });
547
+ return 4;
548
+ }
549
+ const render = categoryEnumerationRender(summaries);
550
+ console.error(message);
551
+ console.error("");
552
+ console.error(_chunkF35VOIQLjs.renderCommandEnvelopeText.call(void 0, { render }).trimEnd());
553
+ console.error("");
554
+ console.error(`Valid categories: ${known.join(", ")}`);
555
+ return 4;
556
+ }
557
+ async function listToolsInCategory(category, emitJson) {
558
+ const client = new (0, _chunk2S5Y3TZPjs.DeeplineClient)();
559
+ const rawTools = await client.listTools({
560
+ categories: category,
561
+ compact: false
562
+ });
563
+ const allTools = await client.listTools({ compact: true });
564
+ const summaries = aggregateCategorySummaries(allTools);
565
+ if (!summaries.some((item) => item.name === category)) {
566
+ return unknownCategoryError(category, summaries, emitJson);
567
+ }
568
+ const rows = rawTools.filter((tool) => _optionalChain([tool, 'access', _6 => _6.categories, 'optionalAccess', _7 => _7.includes, 'call', _8 => _8(category)])).map((tool) => ({
569
+ id: tool.toolId,
570
+ provider: tool.provider,
571
+ required: requiredInputIds(tool),
572
+ pricing: shortPricingHint(tool),
573
+ description: firstSentence(tool.description),
574
+ notConnected: notConnectedSuffix(tool)
575
+ })).sort((a, b) => a.id.localeCompare(b.id));
576
+ const idWidth = rows.reduce((max, row) => Math.max(max, row.id.length), 0);
577
+ const render = {
578
+ sections: [
579
+ {
580
+ title: `${rows.length} tools in ${category}:`,
581
+ lines: rows.map((row) => {
582
+ const id = row.id.padEnd(idWidth);
583
+ const required = row.required.length ? `(${row.required.join(", ")})` : "(no required inputs)";
584
+ const pricing = row.pricing ? ` [${row.pricing}]` : "";
585
+ const description = row.description ? ` - ${row.description}` : "";
586
+ return `${id} ${required}${pricing}${description}${row.notConnected}`;
587
+ })
588
+ },
589
+ {
590
+ title: "next",
591
+ lines: [
592
+ "Run `deepline tools describe <toolId>` for the full contract."
593
+ ]
594
+ }
595
+ ]
596
+ };
597
+ _chunkF35VOIQLjs.printCommandEnvelope.call(void 0,
598
+ {
599
+ category,
600
+ total: rows.length,
601
+ tools: rows,
602
+ commandTemplates: TOOL_COMMAND_TEMPLATES,
603
+ render
604
+ },
605
+ { json: emitJson }
606
+ );
607
+ return 0;
608
+ }
609
+ async function listToolsForCategoryFilter(requestedCategories, emitJson, compact) {
610
+ const client = new (0, _chunk2S5Y3TZPjs.DeeplineClient)();
611
+ const items = (await client.listTools({
612
+ categories: requestedCategories.join(","),
613
+ compact
614
+ })).map(toListedTool).filter(
615
+ (item) => requestedCategories.some(
616
+ (category) => item.categories.includes(category)
617
+ )
618
+ );
619
+ const emptyResult = items.length === 0 ? zeroMatchToolGuidance({ categories: requestedCategories }) : null;
620
+ const render = {
621
+ sections: emptyResult ? zeroMatchRender(emptyResult).sections : [
622
+ {
623
+ title: `${items.length} tools available:`,
624
+ lines: items.map((item) => {
625
+ const cats = item.categories.length ? ` [${item.categories.join(", ")}]` : "";
626
+ const pricing = formatListedToolCost(item);
627
+ return `${item.toolId}${cats} - ${item.description}${pricing ? ` - ${pricing}` : ""}${notConnectedSuffix(item)}`;
628
+ })
629
+ },
630
+ {
631
+ title: "next",
632
+ lines: [
633
+ "Run `deepline tools describe <toolId>` before executing a tool."
634
+ ]
635
+ }
636
+ ]
637
+ };
638
+ const outputItems = compact ? items.map(compactTool) : items;
639
+ _chunkF35VOIQLjs.printCommandEnvelope.call(void 0,
640
+ {
641
+ tools: outputItems,
642
+ count: outputItems.length,
643
+ ...emptyResult ? { emptyResult } : {},
644
+ filters: {
645
+ categories: requestedCategories
646
+ },
647
+ commandTemplates: TOOL_COMMAND_TEMPLATES,
648
+ render
649
+ },
650
+ { json: emitJson }
651
+ );
652
+ return 0;
653
+ }
654
+ async function listTools(category, options = {}) {
655
+ const positional = _nullishCoalesce(_optionalChain([category, 'optionalAccess', _9 => _9.trim, 'call', _10 => _10()]), () => ( ""));
656
+ const flagCategories = (_nullishCoalesce(options.categories, () => ( ""))).split(",").map((item) => item.trim()).filter(Boolean);
657
+ const compact = options.compact !== false;
658
+ const emitJson = options.json === true || _chunkF35VOIQLjs.shouldEmitJson.call(void 0, );
659
+ if (positional && flagCategories.length > 0) {
660
+ const flagIsSameSingle = flagCategories.length === 1 && flagCategories[0] === positional;
661
+ if (!flagIsSameSingle) {
662
+ const message = `Category "${positional}" and --categories ${flagCategories.join(",")} disagree. Pass one: deepline tools list ${positional}`;
663
+ if (emitJson) {
664
+ _chunkF35VOIQLjs.printJson.call(void 0, {
665
+ ok: false,
666
+ exitCode: 2,
667
+ code: "TOOL_LIST_CATEGORY_CONFLICT",
668
+ message,
669
+ next: `deepline tools list ${positional}`
670
+ });
671
+ } else {
672
+ console.error(message);
673
+ }
674
+ return 2;
675
+ }
676
+ }
677
+ if (positional) {
678
+ return listToolsInCategory(positional, emitJson);
679
+ }
680
+ if (flagCategories.length > 0) {
681
+ return listToolsForCategoryFilter(flagCategories, emitJson, compact);
682
+ }
683
+ return listToolCategories(emitJson, compact);
684
+ }
685
+ async function grepTools(queryInput, options = {}) {
686
+ const query = queryInput.trim();
687
+ if (!query) {
688
+ console.error("Usage: deepline tools grep <query> [--json]");
689
+ return 1;
690
+ }
691
+ const client = new (0, _chunk2S5Y3TZPjs.DeeplineClient)();
692
+ const requestedCategories = options.categories ? options.categories.split(",").map((item) => item.trim()).filter(Boolean) : [];
693
+ const mode = _nullishCoalesce(options.mode, () => ( "all"));
694
+ const jsonOutput = options.json === true;
695
+ let apiCompact = !jsonOutput;
696
+ if (typeof options.compact === "boolean") {
697
+ apiCompact = options.compact;
698
+ }
699
+ const tools = (await client.listTools({
700
+ grep: query,
701
+ grepMode: mode,
702
+ ...options.categories ? { categories: options.categories } : {},
703
+ compact: apiCompact
704
+ })).map(toListedTool).filter(
705
+ (item) => requestedCategories.length === 0 || requestedCategories.some(
706
+ (category) => item.categories.includes(category)
707
+ )
708
+ ).filter(
709
+ (item) => apiCompact ? true : matchesGrepQuery(
710
+ {
711
+ id: item.toolId,
712
+ toolId: item.toolId,
713
+ provider: item.provider,
714
+ displayName: item.displayName,
715
+ description: item.description,
716
+ categories: item.categories,
717
+ operation: item.operation,
718
+ operationAliases: item.operationAliases,
719
+ inputSchema: item.inputSchema,
720
+ outputSchema: item.outputSchema,
721
+ inputFields: item.inputFields
722
+ },
723
+ query,
724
+ mode
725
+ )
726
+ );
727
+ const shouldCompact = apiCompact;
728
+ const outputTools = shouldCompact ? tools.slice(0, 8).map(compactTool) : tools;
729
+ const emptyResult = tools.length === 0 ? zeroMatchToolGuidance({
730
+ categories: requestedCategories,
731
+ query,
732
+ mode
733
+ }) : null;
734
+ _chunkF35VOIQLjs.printCommandEnvelope.call(void 0,
735
+ {
736
+ tools: outputTools,
737
+ count: outputTools.length,
738
+ query,
739
+ grep: {
740
+ mode,
741
+ terms: parseGrepTerms(query, mode)
742
+ },
743
+ filters: {
744
+ categories: requestedCategories
745
+ },
746
+ ...emptyResult ? {
747
+ emptyResult,
748
+ render: zeroMatchRender(emptyResult)
749
+ } : {},
750
+ commandTemplates: TOOL_COMMAND_TEMPLATES
751
+ },
752
+ { json: options.json || _chunkF35VOIQLjs.shouldEmitJson.call(void 0, ) }
753
+ );
754
+ return 0;
755
+ }
756
+ function numericToolField(tool, field) {
757
+ const value = tool[field];
758
+ return typeof value === "number" ? value : void 0;
759
+ }
760
+ function compactTool(tool) {
761
+ const listed = toListedTool(tool);
762
+ const searchScore = numericToolField(tool, "searchScore");
763
+ const search_score = numericToolField(tool, "search_score");
764
+ return {
765
+ id: listed.id,
766
+ toolId: listed.toolId,
767
+ ...search_score !== void 0 ? { search_score } : {},
768
+ ...searchScore !== void 0 ? { searchScore } : {},
769
+ provider: listed.provider,
770
+ displayName: listed.displayName,
771
+ description: listed.description,
772
+ categories: listed.categories,
773
+ type: listed.type,
774
+ executeCommand: listed.executeCommand
775
+ };
776
+ }
777
+ function playIdentifiers(play) {
778
+ return [play.name, play.reference, ..._nullishCoalesce(play.aliases, () => ( []))].filter((value) => Boolean(_optionalChain([value, 'optionalAccess', _11 => _11.trim, 'call', _12 => _12()]))).map((value) => value.trim());
779
+ }
780
+ async function findPlayForToolId(client, toolId) {
781
+ const requested = toolId.trim();
782
+ if (!requested) {
783
+ return null;
784
+ }
785
+ const plays = await client.searchPlays({ query: requested, compact: true });
786
+ return _nullishCoalesce(plays.find((play) => playIdentifiers(play).includes(requested)), () => ( null));
787
+ }
788
+ function isMissingToolMetadataError(error) {
789
+ return error instanceof _chunk7P5AA3SNjs.DeeplineError && error.statusCode === 404;
790
+ }
791
+ function playAliasToolErrorMessage(toolId, play) {
792
+ const playName = _nullishCoalesce(play.reference, () => ( play.name));
793
+ return `${toolId} is a play, not a tool.
794
+ Use: deepline plays run ${playName} --input '{...}'
795
+ Inspect its schema with: deepline plays describe ${playName} --json`;
796
+ }
797
+ function printPlayAliasToolError(toolId, play) {
798
+ console.error(playAliasToolErrorMessage(toolId, play));
799
+ }
800
+ function isPlayLikeTool(tool) {
801
+ const record = tool;
802
+ if (record.isPlay === true || record.is_play === true) return true;
803
+ const playExpansion = recordField(record, "playExpansion", "play_expansion");
804
+ if (Object.keys(playExpansion).length > 0) return true;
805
+ const toolId = typeof record.toolId === "string" ? record.toolId : "";
806
+ return toolId.endsWith("_waterfall");
807
+ }
808
+ function isMonitorTypeTool(tool) {
809
+ return stringField2(tool, "kind") === "monitor_type";
810
+ }
811
+ function playReferenceForTool(tool) {
812
+ const record = tool;
813
+ const declared = stringField2(record, "playReference", "play_reference");
814
+ if (declared.startsWith("prebuilt/")) {
815
+ return declared;
816
+ }
817
+ return null;
818
+ }
819
+ function playSearchCommandForToolId(toolId) {
820
+ return `deepline search --type prebuilts ${JSON.stringify(toolId.replace(/_/g, " "))} --json`;
821
+ }
822
+ function playRunCommandForTool(tool, toolId, input) {
823
+ const playReference = playReferenceForTool(tool);
824
+ if (!playReference) return playSearchCommandForToolId(toolId);
825
+ const inputArg = input === void 0 ? "'{...}'" : `'${JSON.stringify(input)}'`;
826
+ return `deepline plays run ${playReference} --input ${inputArg}`;
827
+ }
828
+ function playLikeToolExecuteErrorMessage(toolId, tool) {
829
+ const playReference = tool ? playReferenceForTool(tool) : null;
830
+ const nextStep = playReference ? `Use: deepline plays run ${playReference} --input '{...}'` : `Find the maintained workflow with: ${playSearchCommandForToolId(toolId)}`;
831
+ return [
832
+ `${toolId} is a workflow/play entry, not an atomic provider tool.`,
833
+ nextStep,
834
+ 'Or search provider tools only with: deepline search --type tools "<query>" --json'
835
+ ].join("\n");
836
+ }
837
+ function printPlayLikeToolExecuteError(toolId, tool) {
838
+ console.error(playLikeToolExecuteErrorMessage(toolId, tool));
839
+ }
840
+ function registerToolsCommands(program) {
841
+ const tools = program.command("tools").description(
842
+ "Search by intent or structured filters, describe, and execute atomic provider tools."
843
+ ).addHelpText(
844
+ "after",
845
+ `
846
+ Concepts:
847
+ Tools are atomic provider/API operations. Plays are workflows and must be run
848
+ through the plays namespace.
849
+
850
+ Common commands:
851
+ deepline search --type tools email --json
852
+ deepline tools describe hunter_email_verifier --json
853
+ deepline tools describe hunter_email_verifier --pricing-only --json
854
+ deepline tools execute hunter_email_verifier --input '{"email":"a@b.com"}'
855
+ deepline billing usage --request-id <job_id> --json
856
+
857
+ Output:
858
+ Use describe for tool contracts.
859
+ Use execute to run a tool.
860
+ Read pricing before execution; use the returned next.billing command for its
861
+ exact charge. Workspace balance changes also include other callers' activity.
862
+ `
863
+ );
864
+ tools.command("list [category]").description("Browse tool categories, or list every tool in a category.").addHelpText(
865
+ "after",
866
+ `
867
+ Notes:
868
+ Bare \`tools list\` prints the category enumeration: one line per category with
869
+ its tool count and definition. Pass a category to list every tool in it, one
870
+ succinct row each (required inputs, Deepline pricing hint, first sentence).
871
+ The listing is exhaustive and never truncated. Use search for ranked discovery
872
+ by intent, aliases, descriptions, and schema fields.
873
+
874
+ --categories is a back-compat inventory filter. Passing it alone returns the
875
+ legacy flat inventory envelope (one row per tool). The positional category is
876
+ the newer exhaustive per-category view. If both are given they must name the
877
+ same category (the positional view wins); otherwise it is a usage error.
878
+
879
+ Examples:
880
+ deepline tools list
881
+ deepline tools list email_finder
882
+ deepline tools list email_finder --json
883
+ deepline tools list --categories email_finder --json
884
+ deepline search --type tools email --json
885
+ `
886
+ ).option(
887
+ "--categories <categories>",
888
+ "Comma-separated categories filter (back-compat alias for the positional)"
889
+ ).option("--compact", "Drop verbose fields from JSON output").option("--json", "Emit JSON output. Also automatic when stdout is piped").action(async (category, options) => {
890
+ process.exitCode = await listTools(category, {
891
+ categories: typeof options.categories === "string" ? options.categories : void 0,
892
+ compact: options.compact !== false,
893
+ json: Boolean(options.json)
894
+ });
895
+ });
896
+ _chunkWQICC2B3js.registerDeprecatedSearchCommand.call(void 0, tools, () => ["tools", "monitors"]);
897
+ tools.command("grep <query>").description(
898
+ "Literal grep over tool ids, descriptions, categories, and input fields."
899
+ ).addHelpText(
900
+ "after",
901
+ `
902
+ Notes:
903
+ Literal registry filtering. Terms are matched case-insensitively against tool
904
+ ids, provider, display name, description, categories, aliases, and input
905
+ fields. Use --mode phrase for exact phrase matching, --mode any for OR, and
906
+ the default --mode all for AND.
907
+
908
+ Examples:
909
+ deepline tools grep email --categories email_finder --json
910
+ deepline tools grep "phone validate" --mode all --json
911
+ deepline tools grep hunter --mode phrase --json
912
+ `
913
+ ).option(
914
+ "--categories <categories>",
915
+ "Comma-separated categories to filter inventory"
916
+ ).option("--mode <mode>", "Grep matching mode: all, any, or phrase").option("--compact", "Drop verbose fields from JSON output").option("--json", "Emit JSON output. Also automatic when stdout is piped").action(async (query, options) => {
917
+ const mode = options.mode === "any" || options.mode === "phrase" ? options.mode : "all";
918
+ process.exitCode = await grepTools(query, {
919
+ json: options.json,
920
+ compact: options.compact,
921
+ categories: options.categories,
922
+ mode
923
+ });
924
+ });
925
+ const addToolMetadataCommand = (command) => command.description("Show metadata for a tool.").addHelpText(
926
+ "after",
927
+ `
928
+ Notes:
929
+ Shows the compact agent contract by default: what the tool does, cost,
930
+ required inputs, play getters, input and full Deepline response examples,
931
+ and a ctx.tools.execute snippet. Tool responses live at toolResponse.rawV2;
932
+ preserve the nesting shown in the tool's example. Schemas and examples are
933
+ separate describe fields.
934
+ get is accepted as a compatibility alias for describe.
935
+
936
+ Examples:
937
+ deepline tools describe hunter_email_verifier
938
+ deepline tools describe hunter_email_verifier --pricing-only
939
+ deepline tools describe hunter_email_verifier --pricing-only --json
940
+ deepline tools describe hunter_email_verifier --schema-only
941
+ deepline tools describe hunter_email_verifier --examples-only
942
+ deepline tools describe hunter_email_verifier --json
943
+ deepline tools describe deeplineagent --model openai/gpt-5.6-luna --json
944
+ deepline tools describe ai_inference --estimate-payload @payload.json --json
945
+ deepline tools describe ai_evaluate --estimate-payload @payload.json --json
946
+ deepline tools execute hunter_email_verifier --input '{"email":"a@b.com"}'
947
+ `
948
+ ).option("--json", "Emit JSON output. Also automatic when stdout is piped").option(
949
+ "--model <model>",
950
+ "For language tools, include AI Gateway metadata; for ai_evaluate, set the quote payload model"
951
+ ).option(
952
+ "--estimate-payload <payload>",
953
+ "Quote an ai_evaluate, ai_inference, or deeplineagent JSON payload (inline or @file)"
954
+ ).option("--pricing-only", "Only print pricing and billing semantics").option("--schema-only", "Only print input schema fields").option(
955
+ "--examples-only",
956
+ "Only print input payload and full Deepline execution response examples"
957
+ ).option("--getters-only", "Only print extracted list/value getters").addOption(
958
+ new (0, _commander.Option)(
959
+ "--compact",
960
+ "Compatibility alias for the default compact view"
961
+ ).hideHelp()
962
+ ).addOption(
963
+ new (0, _commander.Option)(
964
+ "--contract-json",
965
+ "Compatibility alias for compact contract JSON"
966
+ ).hideHelp()
967
+ ).action(async (toolId, options) => {
968
+ process.exitCode = await getTool(toolId, {
969
+ json: Boolean(options.json),
970
+ compact: Boolean(options.compact),
971
+ contractJson: Boolean(options.contractJson),
972
+ pricingOnly: Boolean(options.pricingOnly),
973
+ schemaOnly: Boolean(options.schemaOnly),
974
+ examplesOnly: Boolean(options.examplesOnly),
975
+ gettersOnly: Boolean(options.gettersOnly),
976
+ model: typeof options.model === "string" ? options.model : void 0,
977
+ estimatePayload: typeof options.estimatePayload === "string" ? options.estimatePayload : void 0
978
+ });
979
+ });
980
+ addToolMetadataCommand(tools.command("describe <toolId>").alias("get"));
981
+ tools.command("execute <toolId>").description("Execute a tool by id.").addHelpText(
982
+ "after",
983
+ `
984
+ Notes:
985
+ Use tools for one atomic provider/API operation. Use plays for composed workflows,
986
+ waterfalls, row maps, checkpoints, and retries.
987
+ Calling a provider-backed tool can spend Deepline credits. Use --json for the
988
+ stable result payload plus output preview and debugging helpers.
989
+ Read pricing first with tools describe <toolId> --pricing-only --json.
990
+ Use the returned next.billing command to look up this execution's exact charge;
991
+ workspace balance changes also include other callers' activity.
992
+ --timeout sets this CLI request's HTTP deadline; it does not cancel provider work.
993
+
994
+ Examples:
995
+ deepline tools execute hunter_email_verifier --input '{"email":"a@b.com"}'
996
+ deepline tools describe hunter_email_verifier --pricing-only --json
997
+ deepline billing usage --request-id <job_id> --json
998
+ deepline tools execute bounceban_verify_bulk --input @batch.json --timeout 10m --json
999
+ deepline tools execute hunter_email_verifier -p email=a@b.com
1000
+ deepline tools execute test_rate_limit --input '{"key":"smoke"}' --timeout 90s --json
1001
+ deepline tools execute test_rate_limit --input '{"key":"smoke"}' --json | jq '.status'
1002
+ deepline tools execute free_simple_company_search --input '{"sql":"SELECT company_name FROM companies LIMIT 10"}' --out companies.csv
1003
+ `
1004
+ ).option(
1005
+ "-p, --param <key=value>",
1006
+ "Pass one parameter. Repeat for multiple values.",
1007
+ (value, acc) => {
1008
+ acc.push(value);
1009
+ return acc;
1010
+ },
1011
+ []
1012
+ ).option(
1013
+ "--json [payload]",
1014
+ "Emit JSON output. Use `--input` or `--payload` for passing JSON params."
1015
+ ).option(
1016
+ "--input <payload>",
1017
+ "Merge a JSON object or @file path into the tool params"
1018
+ ).option(
1019
+ "--payload <payload>",
1020
+ "Merge a JSON object or @file path into the tool params"
1021
+ ).option(
1022
+ "--timeout <duration>",
1023
+ "Client-side HTTP deadline (for example 90s, 5m, or 1h; bare numbers are seconds); it does not cancel provider work"
1024
+ ).option(
1025
+ "--output-format <format>",
1026
+ "Output format: auto, csv, csv_file, json, or json_file"
1027
+ ).option("-o, --out <path>", "Write row-shaped tool output to this CSV path").option(
1028
+ "--no-preview",
1029
+ "Only print the extracted output path when applicable"
1030
+ ).option(
1031
+ "--idempotency-key <key>",
1032
+ "Stable key for retrying or recovering this tool execution"
1033
+ ).option(
1034
+ "--recover",
1035
+ "Generate or reuse a saved idempotency key for safe recovery"
1036
+ ).option(
1037
+ "--recovery-timeout-ms <milliseconds>",
1038
+ "Maximum wait for a keyed execution to finish (default: 900000)"
1039
+ ).action(async (toolId, options) => {
1040
+ const args = [
1041
+ toolId,
1042
+ ...options.param.flatMap((value) => ["--param", value]),
1043
+ ...options.json === true ? ["--json"] : [],
1044
+ ...typeof options.json === "string" ? ["--json", options.json] : [],
1045
+ ...options.input ? ["--input", options.input] : [],
1046
+ ...options.payload ? ["--payload", options.payload] : [],
1047
+ ...options.timeout ? ["--timeout", options.timeout] : [],
1048
+ ...options.outputFormat ? ["--output-format", options.outputFormat] : [],
1049
+ ...options.out ? ["--out", options.out] : [],
1050
+ ...options.preview === false ? ["--no-preview"] : [],
1051
+ ...options.idempotencyKey ? ["--idempotency-key", options.idempotencyKey] : [],
1052
+ ...options.recover ? ["--recover"] : [],
1053
+ ...options.recoveryTimeoutMs ? ["--recovery-timeout-ms", options.recoveryTimeoutMs] : []
1054
+ ];
1055
+ process.exitCode = await executeTool(args);
1056
+ });
1057
+ }
1058
+ async function getTool(toolId, options = {}) {
1059
+ if (!toolId) {
1060
+ console.error("Usage: deepline tools describe <toolId> [--json]");
1061
+ return 1;
1062
+ }
1063
+ const client = new (0, _chunk2S5Y3TZPjs.DeeplineClient)();
1064
+ let tool;
1065
+ try {
1066
+ tool = await client.getTool(toolId);
1067
+ } catch (error) {
1068
+ if (isMissingToolMetadataError(error)) {
1069
+ const play = await findPlayForToolId(client, toolId);
1070
+ if (play) {
1071
+ printPlayAliasToolError(toolId, play);
1072
+ return 2;
1073
+ }
1074
+ }
1075
+ throw error;
1076
+ }
1077
+ let inferenceQuote = null;
1078
+ if (options.estimatePayload) {
1079
+ if (toolId !== "deeplineagent" && toolId !== "ai_inference" && toolId !== "ai_evaluate") {
1080
+ console.error(
1081
+ "--estimate-payload is only supported for ai_evaluate, deeplineagent, and ai_inference."
1082
+ );
1083
+ return 2;
1084
+ }
1085
+ const estimatePayload = parseJsonObjectArgument(
1086
+ options.estimatePayload,
1087
+ "--estimate-payload"
1088
+ );
1089
+ if (options.model && estimatePayload.model === void 0) {
1090
+ estimatePayload.model = options.model;
1091
+ }
1092
+ inferenceQuote = await client.quoteInferenceTool(toolId, estimatePayload);
1093
+ }
1094
+ const modelDescription = options.model && (toolId === "deeplineagent" || toolId === "ai_inference") ? await client.describeModel(options.model) : null;
1095
+ if (options.model && !modelDescription && toolId !== "ai_evaluate") {
1096
+ console.error(
1097
+ "--model is only supported for deeplineagent and ai_inference."
1098
+ );
1099
+ return 2;
1100
+ }
1101
+ const onlyModes = [
1102
+ options.pricingOnly,
1103
+ options.schemaOnly,
1104
+ options.examplesOnly,
1105
+ options.gettersOnly
1106
+ ].filter(Boolean).length;
1107
+ if (onlyModes > 1) {
1108
+ console.error(
1109
+ "Use only one of --pricing-only, --schema-only, --examples-only, or --getters-only."
1110
+ );
1111
+ return 2;
1112
+ }
1113
+ if (options.pricingOnly) {
1114
+ const lines = toolPricingOnlyLines(tool, toolId);
1115
+ if (inferenceQuote)
1116
+ lines.push(...inferenceQuoteSummaryLines(inferenceQuote));
1117
+ _chunkF35VOIQLjs.printCommandEnvelope.call(void 0,
1118
+ {
1119
+ toolId: String(tool.toolId || toolId),
1120
+ cost: Capability.fromCatalogEntry(tool).describe().customerCost(),
1121
+ ...modelDescription ? { modelOptions: modelDescription } : {},
1122
+ ...isMonitorTypeTool(tool) ? { pricing: recordField(tool, "pricing") } : {},
1123
+ ...inferenceQuote ? { inferenceQuote } : {}
1124
+ },
1125
+ {
1126
+ json: Boolean(options.json || options.contractJson),
1127
+ text: `${lines.join("\n")}
1128
+ `
1129
+ }
1130
+ );
1131
+ return 0;
1132
+ }
1133
+ if ((options.schemaOnly || options.examplesOnly || options.gettersOnly) && !isMonitorTypeTool(tool) && !isPlayLikeTool(tool) && (options.json || options.contractJson)) {
1134
+ const contract = toolContractJsonForDescribe(tool, toolId);
1135
+ _chunkF35VOIQLjs.printCompactJson.call(void 0, {
1136
+ toolId: contract.toolId,
1137
+ ...options.schemaOnly ? {
1138
+ inputSchema: contract.inputSchema,
1139
+ inputFields: contract.inputFields,
1140
+ outputSchema: contract.outputSchema,
1141
+ outputFields: contract.outputFields,
1142
+ responseSchema: contract.responseSchema
1143
+ } : options.examplesOnly ? {
1144
+ examples: _nullishCoalesce(contract.examples, () => ( [])),
1145
+ responseAccess: contract.responseAccess,
1146
+ getters: contract.getters,
1147
+ executeCommand: contract.executeCommand
1148
+ } : {
1149
+ getters: contract.getters,
1150
+ responseAccess: contract.responseAccess
1151
+ },
1152
+ ...modelDescription ? { modelOptions: modelDescription } : {},
1153
+ ...inferenceQuote ? { inferenceQuote } : {}
1154
+ });
1155
+ return 0;
1156
+ }
1157
+ if (options.contractJson) {
1158
+ _chunkF35VOIQLjs.printCompactJson.call(void 0, {
1159
+ ...toolContractJsonForDescribe(tool, toolId),
1160
+ ...modelDescription ? { modelOptions: modelDescription } : {},
1161
+ ...inferenceQuote ? { inferenceQuote } : {}
1162
+ });
1163
+ return 0;
1164
+ }
1165
+ const emitJson = options.json === true;
1166
+ if (emitJson) {
1167
+ _chunkF35VOIQLjs.printCompactJson.call(void 0, {
1168
+ ...toolMetadataJsonForDescribe(tool, toolId),
1169
+ ...modelDescription ? { modelOptions: modelDescription } : {},
1170
+ ...inferenceQuote ? { inferenceQuote } : {}
1171
+ });
1172
+ return 0;
1173
+ }
1174
+ if (options.schemaOnly) {
1175
+ printToolSchemaOnly(tool, toolId);
1176
+ if (inferenceQuote) printInferenceQuoteSummary(inferenceQuote);
1177
+ return 0;
1178
+ }
1179
+ if (options.examplesOnly) {
1180
+ printToolExamplesOnly(tool, toolId);
1181
+ if (inferenceQuote) printInferenceQuoteSummary(inferenceQuote);
1182
+ return 0;
1183
+ }
1184
+ if (options.gettersOnly) {
1185
+ printToolGettersOnly(tool, toolId);
1186
+ if (inferenceQuote) printInferenceQuoteSummary(inferenceQuote);
1187
+ return 0;
1188
+ }
1189
+ if (options.compact) {
1190
+ printCompactToolContract(tool, toolId);
1191
+ if (modelDescription) {
1192
+ process.stdout.write(`
1193
+ ${formatModelDescription(modelDescription)}`);
1194
+ }
1195
+ if (inferenceQuote) printInferenceQuoteSummary(inferenceQuote);
1196
+ return 0;
1197
+ }
1198
+ if (_chunkF35VOIQLjs.shouldEmitJson.call(void 0, )) {
1199
+ _chunkF35VOIQLjs.printCompactJson.call(void 0, {
1200
+ ...toolContractJsonForDescribe(tool, toolId),
1201
+ ...modelDescription ? { modelOptions: modelDescription } : {},
1202
+ ...inferenceQuote ? { inferenceQuote } : {}
1203
+ });
1204
+ return 0;
1205
+ }
1206
+ printCompactToolContract(tool, toolId);
1207
+ if (modelDescription) {
1208
+ process.stdout.write(`
1209
+ ${formatModelDescription(modelDescription)}`);
1210
+ }
1211
+ if (inferenceQuote) printInferenceQuoteSummary(inferenceQuote);
1212
+ return 0;
1213
+ }
1214
+ function inferenceQuoteSummaryLines(_quote) {
1215
+ return [
1216
+ "",
1217
+ "Inference quote:",
1218
+ "- Temporary hold: priced estimate (minimum 0.02 credits)",
1219
+ "- Final charge: actual usage"
1220
+ ];
1221
+ }
1222
+ function printInferenceQuoteSummary(quote) {
1223
+ for (const line of inferenceQuoteSummaryLines(quote)) console.log(line);
1224
+ }
1225
+ function toolContractJsonForDescribe(tool, requestedToolId) {
1226
+ const toolId = String(tool.toolId || requestedToolId);
1227
+ const inputFields = toolInputFieldsForDisplay(
1228
+ recordField(tool, "inputSchema", "input_schema")
1229
+ );
1230
+ const inputSchema = publicToolInputSchemaForDescribe(
1231
+ recordField(tool, "inputSchema", "input_schema")
1232
+ );
1233
+ const outputSchemaRecord = recordField(tool, "outputSchema", "output_schema");
1234
+ const outputFields = toolOutputFieldsForDisplay(outputSchemaRecord);
1235
+ const usageGuidance = recordField(tool, "usageGuidance", "usage_guidance");
1236
+ const guidance = recordField(tool, "guidance");
1237
+ const toolExecutionResult = recordField(
1238
+ usageGuidance,
1239
+ "toolExecutionResult",
1240
+ "tool_execution_result"
1241
+ );
1242
+ const extractedLists = extractionContractEntries(
1243
+ arrayField2(toolExecutionResult, "extractedLists", "extracted_lists")
1244
+ );
1245
+ const extractedValues = extractionContractEntries(
1246
+ arrayField2(toolExecutionResult, "extractedValues", "extracted_values")
1247
+ );
1248
+ const pricing = Capability.fromCatalogEntry(tool).describe().customerCost();
1249
+ const executionMetadataRecord = recordField(
1250
+ tool,
1251
+ "executionMetadata",
1252
+ "execution_metadata"
1253
+ );
1254
+ const executionMetadata = Object.keys(executionMetadataRecord).length > 0 ? executionMetadataRecord : null;
1255
+ const batchCapabilityRecord = recordField(
1256
+ tool,
1257
+ "batchCapability",
1258
+ "batch_capability"
1259
+ );
1260
+ const batchCapability = Object.keys(batchCapabilityRecord).length > 0 ? batchCapabilityRecord : null;
1261
+ const deprecation = recordField(tool, "deprecation");
1262
+ const replacementToolId = stringField2(
1263
+ deprecation,
1264
+ "replacementToolId",
1265
+ "replacement_tool_id"
1266
+ );
1267
+ const deprecationMessage = stringField2(deprecation, "message");
1268
+ const deprecationExecution = stringField2(deprecation, "execution");
1269
+ const deprecated = tool.deprecated === true || stringField2(tool, "credentialStatus", "credential_status") === "deprecated";
1270
+ const starterScript = !deprecated && !isPlayLikeTool(tool) && extractedLists.length > 0 ? starterScriptJson(
1271
+ seedToolListScript({
1272
+ toolId,
1273
+ payload: samplePayloadForInputFields(inputFields),
1274
+ rows: []
1275
+ })
1276
+ ) : null;
1277
+ const executeCommand = deprecated && replacementToolId ? `deepline tools execute ${replacementToolId} --input '{...}' --json` : isPlayLikeTool(tool) ? playRunCommandForTool(tool, toolId) : `deepline tools execute ${toolId} --input '{...}' --json`;
1278
+ return {
1279
+ schemaVersion: 1,
1280
+ toolId,
1281
+ provider: tool.provider,
1282
+ displayName: tool.displayName,
1283
+ cost: pricing,
1284
+ description: tool.description,
1285
+ ...Object.keys(guidance).length > 0 ? { guidance } : {},
1286
+ categories: tool.categories,
1287
+ ...deprecated ? {
1288
+ deprecated: true,
1289
+ callable: tool.callable !== false,
1290
+ deprecation: {
1291
+ replacementToolId,
1292
+ message: deprecationMessage,
1293
+ ...deprecationExecution ? { execution: deprecationExecution } : {}
1294
+ }
1295
+ } : {},
1296
+ inputFields: inputFields.map(inputFieldJsonForDescribe),
1297
+ inputSchema,
1298
+ ...isRecord(tool.responseSchema) ? { responseSchema: tool.responseSchema } : {},
1299
+ ...Array.isArray(tool.examples) ? { examples: tool.examples } : {},
1300
+ responseAccess: "result.toolResponse.rawV2",
1301
+ ...Object.keys(outputSchemaRecord).length > 0 ? {
1302
+ outputSchema: publicToolInputSchemaForDescribe(outputSchemaRecord),
1303
+ outputFields: outputFields.map(inputFieldJsonForDescribe)
1304
+ } : {},
1305
+ ...executionMetadata ? { executionMetadata } : {},
1306
+ ...batchCapability ? { batchCapability } : {},
1307
+ getters: {
1308
+ extractedLists,
1309
+ extractedValues
1310
+ },
1311
+ executeCommand,
1312
+ ...starterScript ? { starterScript } : {}
1313
+ };
1314
+ }
1315
+ function extractionContractEntries(entries) {
1316
+ return entries.flatMap((entry) => {
1317
+ if (!isRecord(entry)) return [];
1318
+ const name = stringField2(entry, "name");
1319
+ const expression = stringField2(entry, "expression");
1320
+ return name && expression ? [{ name, expression }] : [];
1321
+ });
1322
+ }
1323
+ function printMonitorTypeFilters(tool) {
1324
+ const schema = recordField(tool, "payload_schema", "payloadSchema");
1325
+ const properties = recordField(schema, "properties");
1326
+ const required = new Set(
1327
+ arrayField2(schema, "required").filter(
1328
+ (v) => typeof v === "string"
1329
+ )
1330
+ );
1331
+ const names = Object.keys(properties);
1332
+ if (!names.length) {
1333
+ console.log("Deploy filters: none");
1334
+ return;
1335
+ }
1336
+ console.log("Deploy filters (set in the monitor payload):");
1337
+ for (const name of names) {
1338
+ const field = isRecord(properties[name]) ? properties[name] : {};
1339
+ const star = required.has(name) ? "*" : "";
1340
+ const enumVals = arrayField2(field, "enum").filter(
1341
+ (v) => typeof v === "string"
1342
+ );
1343
+ const type = enumVals.length ? `one of [${enumVals.join(", ")}]` : stringField2(field, "type") || "string";
1344
+ const desc = stringField2(field, "description");
1345
+ console.log(`- ${name}${star}: ${type}${desc ? ` - ${desc}` : ""}`);
1346
+ }
1347
+ }
1348
+ function printMonitorTypeFilterExamples(tool) {
1349
+ const documentation = recordField(tool, "documentation");
1350
+ const fields = recordField(documentation, "fields");
1351
+ const examples = Object.entries(fields).flatMap(([name, rawField]) => {
1352
+ const grammar = recordField(isRecord(rawField) ? rawField : {}, "grammar");
1353
+ const example = stringField2(grammar, "example");
1354
+ const values = [
1355
+ ...arrayField2(grammar, "examples").filter(
1356
+ (value) => typeof value === "string" && Boolean(value)
1357
+ ),
1358
+ ...example ? [example] : []
1359
+ ];
1360
+ return [...new Set(values)].map((example2) => ({ name, example: example2 }));
1361
+ });
1362
+ if (examples.length === 0) return;
1363
+ console.log("");
1364
+ console.log("Filter examples:");
1365
+ for (const { name, example } of examples) {
1366
+ console.log(`- ${name}: ${example}`);
1367
+ }
1368
+ }
1369
+ function printMonitorTypeStreams(tool) {
1370
+ const streams = arrayField2(tool, "streams", "output_streams").filter(
1371
+ isRecord
1372
+ );
1373
+ if (!streams.length) return;
1374
+ console.log("");
1375
+ console.log("Filter columns (a play's sqlListeners.where, per stream):");
1376
+ for (const stream of streams) {
1377
+ const name = stringField2(stream, "stream");
1378
+ const cols = arrayField2(stream, "columns").filter(isRecord).map((col) => stringField2(col, "name")).filter(Boolean);
1379
+ console.log(`- ${name}: ${cols.join(", ")}`);
1380
+ }
1381
+ }
1382
+ function monitorTypePricingLines(tool) {
1383
+ const pricing = recordField(tool, "pricing");
1384
+ const byType = recordField(
1385
+ pricing,
1386
+ "pricing_by_radar_type",
1387
+ "pricingByRadarType"
1388
+ );
1389
+ const keys = Object.keys(byType);
1390
+ if (!keys.length) {
1391
+ return ["Pricing: Deepline credits per accepted event (see --json)"];
1392
+ }
1393
+ const lines = ["Pricing (Deepline credits per accepted event):"];
1394
+ for (const key of keys) {
1395
+ const entry = isRecord(byType[key]) ? byType[key] : {};
1396
+ const credits = numberField2(entry, "deepline_credits", "deeplineCredits");
1397
+ const display = stringField2(entry, "display");
1398
+ const shown = display || (credits !== null ? `${formatDecimal(credits)} credits/event` : "see --json");
1399
+ lines.push(`- ${key}: ${shown}`);
1400
+ }
1401
+ return lines;
1402
+ }
1403
+ function printMonitorTypePricing(tool) {
1404
+ for (const line of monitorTypePricingLines(tool)) console.log(line);
1405
+ }
1406
+ function printMonitorTypeDeploy(tool) {
1407
+ const deploy = recordField(tool, "deploy");
1408
+ const toolId = stringField2(tool, "toolId");
1409
+ const example = stringField2(deploy, "example") || `deepline monitors deploy '{"key":"...","tool":"${toolId}","payload":{...}}'`;
1410
+ console.log("Deploy (a monitor type is deployed, not executed):");
1411
+ console.log(` ${example}`);
1412
+ }
1413
+ function printMonitorTypeContract(tool, requestedToolId) {
1414
+ const toolId = stringField2(tool, "toolId") || requestedToolId;
1415
+ console.log(toolId);
1416
+ const displayName = stringField2(tool, "displayName");
1417
+ if (displayName) console.log(`Best for: ${displayName}`);
1418
+ const description = stringField2(tool, "description");
1419
+ if (description) console.log(`Description: ${description}`);
1420
+ const categories = arrayField2(tool, "categories").filter(
1421
+ (v) => typeof v === "string"
1422
+ );
1423
+ if (categories.length) console.log(`Tags: ${categories.join(", ")}`);
1424
+ console.log("");
1425
+ console.log(
1426
+ "Monitor type \u2014 streams a provider's events into your warehouse. Deploy it, don't execute it."
1427
+ );
1428
+ console.log("");
1429
+ printMonitorTypeFilters(tool);
1430
+ printMonitorTypeFilterExamples(tool);
1431
+ printMonitorTypeStreams(tool);
1432
+ console.log("");
1433
+ printMonitorTypePricing(tool);
1434
+ console.log("");
1435
+ printMonitorTypeDeploy(tool);
1436
+ console.log("");
1437
+ console.log(`More: deepline tools get ${toolId} --json`);
1438
+ }
1439
+ function toolGuidanceLines(guidance) {
1440
+ const record = isRecord(guidance) ? guidance : {};
1441
+ const toolGuidance = stringField2(record, "tool");
1442
+ const providerGuidance = stringField2(record, "provider");
1443
+ return [
1444
+ ...toolGuidance ? [`- This tool: ${toolGuidance}`] : [],
1445
+ ...providerGuidance ? [`- Provider: ${providerGuidance}`] : []
1446
+ ];
1447
+ }
1448
+ function printCompactToolContract(tool, requestedToolId) {
1449
+ if (isMonitorTypeTool(tool)) {
1450
+ printMonitorTypeContract(tool, requestedToolId);
1451
+ return;
1452
+ }
1453
+ const contract = toolContractJsonForDescribe(tool, requestedToolId);
1454
+ const cost = isRecord(contract.cost) ? contract.cost : {};
1455
+ const getters = isRecord(contract.getters) ? contract.getters : {};
1456
+ const listGetters = Array.isArray(getters.extractedLists) ? getters.extractedLists : [];
1457
+ const valueGetters = Array.isArray(getters.extractedValues) ? getters.extractedValues : [];
1458
+ const inputFields = recursiveToolInputFieldsForDisplay(
1459
+ recordField(contract, "inputSchema")
1460
+ );
1461
+ console.log(String(contract.toolId));
1462
+ if (contract.displayName) console.log(`Best for: ${contract.displayName}`);
1463
+ if (typeof contract.description === "string" && contract.description.trim()) {
1464
+ console.log(`Description: ${contract.description.trim()}`);
1465
+ }
1466
+ if (Array.isArray(contract.categories) && contract.categories.length) {
1467
+ console.log(`Tags: ${contract.categories.join(", ")}`);
1468
+ }
1469
+ const guidanceLines = toolGuidanceLines(contract.guidance);
1470
+ if (guidanceLines.length > 0) {
1471
+ console.log(["Guidance:", ...guidanceLines].join("\n"));
1472
+ }
1473
+ printToolOutputArrayShape(contract);
1474
+ printToolExecutionHints(contract);
1475
+ if (contract.deprecated === true) {
1476
+ const deprecation = isRecord(contract.deprecation) ? contract.deprecation : {};
1477
+ const message = stringField2(deprecation, "message");
1478
+ const replacementToolId = stringField2(
1479
+ deprecation,
1480
+ "replacementToolId",
1481
+ "replacement_tool_id"
1482
+ );
1483
+ console.log(
1484
+ contract.callable === false ? "Status: deprecated \u2014 this tool cannot be executed" : "Status: deprecated \u2014 legacy executions forward for compatibility"
1485
+ );
1486
+ if (message) console.log(`Migration: ${message}`);
1487
+ if (replacementToolId) {
1488
+ console.log(
1489
+ `Use: deepline tools execute ${replacementToolId} --input '{...}'`
1490
+ );
1491
+ }
1492
+ console.log("");
1493
+ console.log(
1494
+ `More: deepline tools describe ${replacementToolId || contract.toolId} --json`
1495
+ );
1496
+ return;
1497
+ }
1498
+ printToolPricingOnly(tool, requestedToolId, { heading: "Cost" });
1499
+ if (inputFields.length) {
1500
+ console.log("");
1501
+ console.log("Inputs:");
1502
+ for (const field of inputFields) {
1503
+ if (!isRecord(field)) continue;
1504
+ const name = stringField2(field, "name");
1505
+ if (!name) continue;
1506
+ const required = field.required ? "*" : "";
1507
+ const type = stringField2(field, "type") || "unknown";
1508
+ const description = stringField2(field, "description");
1509
+ const enumValues = Array.isArray(field.enum) ? field.enum : [];
1510
+ const enumSuffix = enumValues.length ? ` enum=${enumValues.map(String).join("|")}` : "";
1511
+ const itemBoundsSuffix = arrayItemBoundsSuffix(field);
1512
+ const defaultSuffix = Object.prototype.hasOwnProperty.call(
1513
+ field,
1514
+ "default"
1515
+ ) ? ` default=${JSON.stringify(field.default)}` : "";
1516
+ console.log(
1517
+ `- ${name}${required}: ${type}${enumSuffix}${itemBoundsSuffix}${defaultSuffix}${description ? ` - ${description}` : ""}`
1518
+ );
1519
+ }
1520
+ }
1521
+ console.log("");
1522
+ printToolExamplesOnly(tool, requestedToolId);
1523
+ const starterScript = isRecord(contract.starterScript) ? contract.starterScript : {};
1524
+ const starterPath = stringField2(starterScript, "path");
1525
+ if (starterPath) {
1526
+ console.log("");
1527
+ console.log(`Starter script: ${starterPath}`);
1528
+ console.log("Copy it into your project and adapt the example input.");
1529
+ }
1530
+ if (listGetters.length || valueGetters.length) {
1531
+ console.log("");
1532
+ console.log("Getters:");
1533
+ if (listGetters.length) console.log("Lists:");
1534
+ for (const entry of listGetters) {
1535
+ if (isRecord(entry))
1536
+ console.log(
1537
+ `- ${stringField2(entry, "name")}: ${playResultExpression(entry)}`
1538
+ );
1539
+ }
1540
+ if (valueGetters.length) console.log("Values:");
1541
+ for (const entry of valueGetters) {
1542
+ if (isRecord(entry))
1543
+ console.log(
1544
+ `- ${stringField2(entry, "name")}: ${playResultExpression(entry)}`
1545
+ );
1546
+ }
1547
+ }
1548
+ console.log("");
1549
+ console.log(
1550
+ "Provider-specific fields: inspect result.toolResponse.rawV2 and its observed envelope. Prefer the declared getters above."
1551
+ );
1552
+ console.log(
1553
+ `More: deepline tools describe ${contract.toolId} --pricing-only | --schema-only | --examples-only | --getters-only | --json`
1554
+ );
1555
+ }
1556
+ function toolPricingOnlyLines(tool, requestedToolId, options = {}) {
1557
+ if (isMonitorTypeTool(tool)) {
1558
+ return monitorTypePricingLines(tool);
1559
+ }
1560
+ const toolId = String(tool.toolId || requestedToolId);
1561
+ const cost = Capability.fromCatalogEntry(tool).describe().customerCost();
1562
+ const pricingModel = stringField2(cost, "pricingModel") || "unknown";
1563
+ const billing = stringField2(cost, "billingSourceLabel") || stringField2(cost, "billingSource") || stringField2(cost, "billingMode") || "unknown";
1564
+ const explicitUnit = stringField2(cost, "unit");
1565
+ const unit = explicitUnit || (pricingModel === "per_page" ? "page" : pricingModel === "per_result" ? "result" : pricingModel === "fixed" ? "call" : pricingModel.replace(/^per_/, "") || "unit");
1566
+ const credits = numberField2(cost, "deeplineCreditsPerPricingUnit");
1567
+ const usd = numberField2(cost, "deeplineUsdPerPricingUnit");
1568
+ const displayText = stringField2(cost, "displayText");
1569
+ const summary = stringField2(cost, "summary");
1570
+ const price = displayText || summary || (credits !== null ? `${formatDecimal(credits)} Deepline credits${usd !== null ? ` / ${formatUsd(usd)}` : ""} per ${unit}` : "pricing unavailable");
1571
+ return [
1572
+ `${_nullishCoalesce(options.heading, () => ( `Pricing: ${toolId}`))}: ${price}`,
1573
+ `Billing: ${billing}`
1574
+ ];
1575
+ }
1576
+ function printToolPricingOnly(tool, requestedToolId, options = {}) {
1577
+ for (const line of toolPricingOnlyLines(tool, requestedToolId, options))
1578
+ console.log(line);
1579
+ }
1580
+ function printToolSchemaOnly(tool, requestedToolId) {
1581
+ if (isMonitorTypeTool(tool)) {
1582
+ printMonitorTypeFilters(tool);
1583
+ printMonitorTypeStreams(tool);
1584
+ return;
1585
+ }
1586
+ const contract = toolContractJsonForDescribe(tool, requestedToolId);
1587
+ const inputFields = recursiveToolInputFieldsForDisplay(
1588
+ recordField(contract, "inputSchema")
1589
+ );
1590
+ console.log(`Schema: ${contract.toolId}`);
1591
+ if (!inputFields.length) {
1592
+ console.log("Inputs: none");
1593
+ } else {
1594
+ console.log("Inputs:");
1595
+ for (const field of inputFields) {
1596
+ const name = typeof field.name === "string" ? field.name : "";
1597
+ if (!name) continue;
1598
+ const required = field.required ? "*" : "";
1599
+ const type = typeof field.type === "string" ? field.type : "unknown";
1600
+ const description = typeof field.description === "string" ? field.description : "";
1601
+ const enumValues = Array.isArray(field.enum) ? field.enum : [];
1602
+ const enumSuffix = enumValues.length ? ` enum=${enumValues.map(String).join("|")}` : "";
1603
+ const itemBoundsSuffix = arrayItemBoundsSuffix(field);
1604
+ const defaultSuffix = Object.prototype.hasOwnProperty.call(
1605
+ field,
1606
+ "default"
1607
+ ) ? ` default=${JSON.stringify(field.default)}` : "";
1608
+ console.log(
1609
+ `- ${name}${required}: ${type}${enumSuffix}${itemBoundsSuffix}${defaultSuffix}${description ? ` - ${description}` : ""}`
1610
+ );
1611
+ }
1612
+ }
1613
+ printToolOutputArrayShape(contract);
1614
+ const declaredSchema = declaredToolJsonSchema(
1615
+ recordField(contract, "inputSchema")
1616
+ );
1617
+ if (declaredSchema) {
1618
+ console.log("Declared input JSON Schema:");
1619
+ console.log(JSON.stringify(declaredSchema, null, 2));
1620
+ }
1621
+ if (isRecord(contract.responseSchema)) {
1622
+ console.log("Deepline execution response JSON Schema:");
1623
+ console.log(JSON.stringify(contract.responseSchema, null, 2));
1624
+ }
1625
+ }
1626
+ function printToolExamplesOnly(tool, requestedToolId) {
1627
+ if (isMonitorTypeTool(tool)) {
1628
+ printMonitorTypeDeploy(tool);
1629
+ return;
1630
+ }
1631
+ if (isPlayLikeTool(tool)) {
1632
+ printPlayLikeToolUsage(tool, requestedToolId);
1633
+ return;
1634
+ }
1635
+ const contract = toolContractJsonForDescribe(tool, requestedToolId);
1636
+ const toolId = String(contract.toolId);
1637
+ const inputFields = Array.isArray(contract.inputFields) ? contract.inputFields : [];
1638
+ const examples = arrayField2(tool, "examples").filter(isRecord);
1639
+ const firstExample = examples[0];
1640
+ const sampleInput = firstExample && isRecord(firstExample.input) ? firstExample.input : _nullishCoalesce(samplePayload(recordField(tool, "samples"), "request"), () => ( samplePayloadForInputFields(inputFields)));
1641
+ console.log("Example input payload:");
1642
+ console.log(JSON.stringify(sampleInput, null, 2));
1643
+ console.log(`Use in a play:`);
1644
+ console.log("```ts");
1645
+ console.log("const result = await ctx.tools.execute({");
1646
+ console.log(` id: '${stableStepIdForTool(toolId)}',`);
1647
+ console.log(` tool: '${toolId}',`);
1648
+ console.log(
1649
+ ` input: ${JSON.stringify(sampleInput || {}, null, 2).replace(/\n/g, "\n ")},`
1650
+ );
1651
+ console.log("});");
1652
+ console.log("const response = result.toolResponse.rawV2;");
1653
+ const getters = isRecord(contract.getters) ? contract.getters : {};
1654
+ const valueGetters = Array.isArray(getters.extractedValues) ? getters.extractedValues : [];
1655
+ const listGetters = Array.isArray(getters.extractedLists) ? getters.extractedLists : [];
1656
+ const firstGetter = [...valueGetters, ...listGetters].find(isRecord);
1657
+ if (firstGetter) {
1658
+ const name = stringField2(firstGetter, "name") || "value";
1659
+ const expression = stringField2(firstGetter, "expression");
1660
+ if (expression)
1661
+ console.log(
1662
+ `const ${safeIdentifier(name)} = ${expression.replace(/^toolExecutionResult\./, "result.")};`
1663
+ );
1664
+ }
1665
+ console.log("```");
1666
+ for (const example of examples) {
1667
+ const description = stringField2(example, "description");
1668
+ if (description) console.log(description);
1669
+ console.log("Example Deepline execution response:");
1670
+ console.log(JSON.stringify(example.response, null, 2));
1671
+ }
1672
+ if (!examples.length)
1673
+ console.log(
1674
+ "No Deepline execution response example is published by this server."
1675
+ );
1676
+ console.log(
1677
+ "Read tool-specific fields from result.toolResponse.rawV2 using the nesting above. In a play, use the declared getters for extracted values and lists. Billing and execution metadata may also be returned."
1678
+ );
1679
+ }
1680
+ function printPlayLikeToolUsage(tool, requestedToolId) {
1681
+ const toolId = String(tool.toolId || requestedToolId);
1682
+ const inputFields = toolInputFieldsForDisplay(
1683
+ recordField(tool, "inputSchema", "input_schema")
1684
+ );
1685
+ const sampleInput = samplePayloadForInputFields(inputFields);
1686
+ const playReference = playReferenceForTool(tool);
1687
+ console.log("Run as a play:");
1688
+ console.log(
1689
+ playRunCommandForTool(
1690
+ tool,
1691
+ toolId,
1692
+ Object.keys(sampleInput).length ? sampleInput : void 0
1693
+ )
1694
+ );
1695
+ if (playReference) {
1696
+ console.log(`deepline plays describe ${playReference} --json`);
1697
+ }
1698
+ }
1699
+ function printToolGettersOnly(tool, requestedToolId) {
1700
+ const contract = toolContractJsonForDescribe(tool, requestedToolId);
1701
+ const getters = isRecord(contract.getters) ? contract.getters : {};
1702
+ const listGetters = Array.isArray(getters.extractedLists) ? getters.extractedLists : [];
1703
+ const valueGetters = Array.isArray(getters.extractedValues) ? getters.extractedValues : [];
1704
+ console.log(`Getters: ${contract.toolId}`);
1705
+ if (!listGetters.length && !valueGetters.length) {
1706
+ console.log(
1707
+ "No generated getters declared. Use --json only if you need raw metadata."
1708
+ );
1709
+ return;
1710
+ }
1711
+ if (listGetters.length) {
1712
+ console.log("Lists:");
1713
+ for (const entry of listGetters) {
1714
+ if (isRecord(entry))
1715
+ console.log(
1716
+ `- ${stringField2(entry, "name")}: ${playResultExpression(entry)}`
1717
+ );
1718
+ }
1719
+ }
1720
+ if (valueGetters.length) {
1721
+ console.log("Values:");
1722
+ for (const entry of valueGetters) {
1723
+ if (isRecord(entry))
1724
+ console.log(
1725
+ `- ${stringField2(entry, "name")}: ${playResultExpression(entry)}`
1726
+ );
1727
+ }
1728
+ }
1729
+ }
1730
+ function sampleValueForField(field) {
1731
+ const name = stringField2(field, "name").toLowerCase();
1732
+ const type = stringField2(field, "type").toLowerCase();
1733
+ if (Object.prototype.hasOwnProperty.call(field, "default"))
1734
+ return field.default;
1735
+ if (name.includes("email")) return "ada@example.com";
1736
+ if (name.includes("domain") || name.includes("website")) return "example.com";
1737
+ if (name.includes("first")) return "Ada";
1738
+ if (name.includes("last")) return "Lovelace";
1739
+ if (name.includes("name")) return "Ada Lovelace";
1740
+ if (type === "integer" || type === "number") return 1;
1741
+ if (type === "boolean") return true;
1742
+ if (type === "array") return [];
1743
+ if (type === "object") return {};
1744
+ return "...";
1745
+ }
1746
+ function samplePayloadForInputFields(fields) {
1747
+ return Object.fromEntries(
1748
+ fields.slice(0, 4).flatMap((field) => {
1749
+ if (!isRecord(field)) return [];
1750
+ const name = stringField2(field, "name");
1751
+ if (!name) return [];
1752
+ return [[name, sampleValueForField(field)]];
1753
+ })
1754
+ );
1755
+ }
1756
+ function stableStepIdForTool(toolId) {
1757
+ return toolId.replace(/^[a-z0-9]+_/, "").replace(/[^a-z0-9_]+/gi, "_") || "tool_call";
1758
+ }
1759
+ function safeIdentifier(name) {
1760
+ const cleaned = name.replace(/[^a-zA-Z0-9_$]+/g, "_").replace(/^[^a-zA-Z_$]+/, "");
1761
+ return cleaned || "value";
1762
+ }
1763
+ function playResultExpression(entry) {
1764
+ return stringField2(entry, "expression").replace(
1765
+ /^toolExecutionResult\./,
1766
+ "result."
1767
+ );
1768
+ }
1769
+ function toolMetadataJsonForDescribe(tool, requestedToolId) {
1770
+ const toolId = String(tool.toolId || requestedToolId);
1771
+ const inputFields = toolInputFieldsForDisplay(
1772
+ recordField(tool, "inputSchema", "input_schema")
1773
+ );
1774
+ const usageGuidance = usageGuidanceWithAccessDefaults(
1775
+ recordField(tool, "usageGuidance", "usage_guidance")
1776
+ );
1777
+ const toolExecutionResult = recordField(
1778
+ usageGuidance,
1779
+ "toolExecutionResult",
1780
+ "tool_execution_result"
1781
+ );
1782
+ const extractedLists = extractionContractEntries(
1783
+ arrayField2(toolExecutionResult, "extractedLists", "extracted_lists")
1784
+ );
1785
+ const starterScript = !isPlayLikeTool(tool) && extractedLists.length > 0 ? starterScriptJson(
1786
+ seedToolListScript({
1787
+ toolId,
1788
+ payload: samplePayloadForInputFields(inputFields),
1789
+ rows: []
1790
+ })
1791
+ ) : null;
1792
+ const observedOutputCommand = isPlayLikeTool(tool) ? playRunCommandForTool(tool, toolId) : `deepline tools execute ${toolId} --input '{...}' --json`;
1793
+ const {
1794
+ cost: _cost,
1795
+ deeplineCreditsPerPricingUnit: _deeplineCreditsPerPricingUnit,
1796
+ deeplineUsdPerPricingUnit: _deeplineUsdPerPricingUnit,
1797
+ deeplineUsdPerCredit: _deeplineUsdPerCredit,
1798
+ deeplinePricingSummary: _deeplinePricingSummary,
1799
+ deeplinePricingDetails: _deeplinePricingDetails,
1800
+ deepline_credits_per_pricing_unit: _snakeDeeplineCreditsPerPricingUnit,
1801
+ deepline_usd_per_pricing_unit: _snakeDeeplineUsdPerPricingUnit,
1802
+ deepline_usd_per_credit: _snakeDeeplineUsdPerCredit,
1803
+ deepline_pricing_summary: _snakeDeeplinePricingSummary,
1804
+ deepline_pricing_details: _snakeDeeplinePricingDetails,
1805
+ ...publicTool
1806
+ } = tool;
1807
+ const outputSchemaRecord = recordField(tool, "outputSchema", "output_schema");
1808
+ return {
1809
+ cost: Capability.fromCatalogEntry(tool).describe().customerCost(),
1810
+ ...publicTool,
1811
+ toolId,
1812
+ provider: tool.provider,
1813
+ displayName: tool.displayName,
1814
+ ...Object.keys(outputSchemaRecord).length > 0 ? {
1815
+ outputSchema: publicToolInputSchemaForDescribe(outputSchemaRecord),
1816
+ outputFields: toolOutputFieldsForDisplay(outputSchemaRecord).map(
1817
+ inputFieldJsonForDescribe
1818
+ )
1819
+ } : {},
1820
+ inputFields: inputFields.map(inputFieldJsonForDescribe),
1821
+ usageGuidance,
1822
+ runtimeOutputHelp: {
1823
+ contract: "Schemas declare field shapes. Examples illustrate input payloads and full Deepline execution responses; they are not observed responses from this call.",
1824
+ getterScope: "extractedValues/extractedLists .get() only works for declared Deepline getters listed in usageGuidance.toolExecutionResult.",
1825
+ rawToolResponse: "Use toolExecutionResult.toolResponse.rawV2 for the complete tool response. Preserve its nesting and sibling fields as shown in examples; use declared getters for extracted values and lists.",
1826
+ invalidGetterHint: "If TypeScript says an extractedValues/extractedLists property does not exist, that field is not a declared Deepline getter.",
1827
+ observeActualShape: observedOutputCommand,
1828
+ observedOutput: observedOutputCommand,
1829
+ forPlayGetterBugs: "Run a tiny play, inspect returned handles with `deepline runs get <run-id> --full --json`, then export row datasets with `deepline runs export`.",
1830
+ executeOutputFields: "tools execute JSON may include output_preview for this direct probe only; play debugging uses run output and returned dataset handles."
1831
+ },
1832
+ ...starterScript ? { starterScript } : {}
1833
+ };
1834
+ }
1835
+ function usageGuidanceWithAccessDefaults(usageGuidance) {
1836
+ if (Object.keys(usageGuidance).length === 0) return usageGuidance;
1837
+ const existingAccess = recordField(usageGuidance, "access");
1838
+ return {
1839
+ ...usageGuidance,
1840
+ prefer: [
1841
+ "Use only the declared extractedLists and extractedValues getters listed below.",
1842
+ "Use toolExecutionResult.toolResponse.rawV2 for the complete tool response, preserving the nesting shown in the response example.",
1843
+ "Schemas declare field shapes; examples illustrate input values and full Deepline execution responses."
1844
+ ],
1845
+ toolExecutionResult: {
1846
+ ...recordField(
1847
+ usageGuidance,
1848
+ "toolExecutionResult",
1849
+ "tool_execution_result"
1850
+ ),
1851
+ toolResponse: {
1852
+ rawV2: "toolResponse.rawV2",
1853
+ view: "toolResponse.view",
1854
+ responseMeta: "toolResponse.responseMeta"
1855
+ }
1856
+ },
1857
+ access: {
1858
+ ...existingAccess,
1859
+ extractedLists: {
1860
+ expression: "toolExecutionResult.extractedLists.<name>.get()",
1861
+ meaning: "Declared Deepline list extractors only."
1862
+ },
1863
+ extractedValues: {
1864
+ expression: "toolExecutionResult.extractedValues.<name>.get()",
1865
+ meaning: "Declared Deepline scalar or normalized object extractors only."
1866
+ },
1867
+ ...existingAccess,
1868
+ rawToolResponse: {
1869
+ expression: "toolExecutionResult.toolResponse.rawV2",
1870
+ meaning: "Complete tool response with its original nesting. Read tool-specific fields here; use declared getters for extracted values and lists."
1871
+ },
1872
+ canonicalToolResponse: {
1873
+ expression: "toolExecutionResult.toolResponse.rawV2",
1874
+ meaning: "Complete tool response with its original nesting and sibling fields."
1875
+ },
1876
+ invalidGetterHint: "If TypeScript says an extractedValues/extractedLists property does not exist, that field is not a declared Deepline getter; read it from toolResponse.rawV2 using the nesting shown in the response example."
1877
+ }
1878
+ };
1879
+ }
1880
+ function singleLineText(value, maxLength = 260) {
1881
+ if (typeof value !== "string") return "";
1882
+ const text = value.replace(/\s+/g, " ").trim();
1883
+ if (text.length <= maxLength) return text;
1884
+ return `${text.slice(0, maxLength - 3).trimEnd()}...`;
1885
+ }
1886
+ function listedToolDescription(tool) {
1887
+ const record = tool;
1888
+ return singleLineText(_nullishCoalesce(_nullishCoalesce(record.bestFor, () => ( record.best_for)), () => ( tool.description)));
1889
+ }
1890
+ function formatListedToolCost(tool) {
1891
+ const record = tool;
1892
+ if (stringField2(record, "billingSource", "billing_source") === "free") {
1893
+ return "Cost: Free";
1894
+ }
1895
+ const pricing = recordField(record, "pricing");
1896
+ const displayText = stringField2(pricing, "displayText", "display_text");
1897
+ return displayText ? `Cost: ${displayText}` : "";
1898
+ }
1899
+ function toolInputFieldsForDisplay(inputSchema) {
1900
+ if (Array.isArray(inputSchema.fields)) {
1901
+ const fields = inputSchema.fields.filter(isRecord);
1902
+ if (!isRecord(inputSchema.jsonSchema)) return fields;
1903
+ const jsonSchemaFields = new Map(
1904
+ recursiveToolInputFieldsForDisplay({
1905
+ jsonSchema: inputSchema.jsonSchema
1906
+ }).flatMap(
1907
+ (field) => typeof field.name === "string" ? [[field.name, field]] : []
1908
+ )
1909
+ );
1910
+ return fields.map((field) => {
1911
+ const jsonSchemaField = typeof field.name === "string" ? jsonSchemaFields.get(field.name) : void 0;
1912
+ const minItems = typeof field.minItems === "number" ? field.minItems : _optionalChain([jsonSchemaField, 'optionalAccess', _13 => _13.minItems]);
1913
+ const maxItems = typeof field.maxItems === "number" ? field.maxItems : _optionalChain([jsonSchemaField, 'optionalAccess', _14 => _14.maxItems]);
1914
+ const items = isRecord(field.items) ? field.items : _optionalChain([jsonSchemaField, 'optionalAccess', _15 => _15.items]);
1915
+ return {
1916
+ ...field,
1917
+ ...isRecord(items) ? { items } : {},
1918
+ ...typeof minItems === "number" ? { minItems } : {},
1919
+ ...typeof maxItems === "number" ? { maxItems } : {}
1920
+ };
1921
+ });
1922
+ }
1923
+ const jsonSchema = isRecord(inputSchema.jsonSchema) ? inputSchema.jsonSchema : inputSchema;
1924
+ const properties = isRecord(jsonSchema.properties) ? jsonSchema.properties : {};
1925
+ const required = Array.isArray(jsonSchema.required) ? new Set(jsonSchema.required.map(String)) : /* @__PURE__ */ new Set();
1926
+ return Object.entries(properties).map(([name, value]) => {
1927
+ const property = isRecord(value) ? value : {};
1928
+ return {
1929
+ name,
1930
+ type: typeof property.type === "string" ? property.type : "unknown",
1931
+ required: required.has(name),
1932
+ description: property.description,
1933
+ ...isRecord(property.items) ? { items: property.items } : {},
1934
+ ...typeof property.minItems === "number" ? { minItems: property.minItems } : {},
1935
+ ...typeof property.maxItems === "number" ? { maxItems: property.maxItems } : {},
1936
+ ...Object.prototype.hasOwnProperty.call(property, "default") ? { default: property.default } : {}
1937
+ };
1938
+ });
1939
+ }
1940
+ function toolOutputFieldsForDisplay(outputSchema) {
1941
+ if (Object.keys(outputSchema).length === 0) return [];
1942
+ return recursiveToolInputFieldsForDisplay({
1943
+ jsonSchema: outputSchema
1944
+ }).filter(
1945
+ (field) => typeof field.name === "string" && field.name.includes("[]")
1946
+ );
1947
+ }
1948
+ function printToolOutputArrayShape(tool) {
1949
+ const outputFields = toolOutputFieldsForDisplay(
1950
+ recordField(isRecord(tool) ? tool : {}, "outputSchema", "output_schema")
1951
+ );
1952
+ if (outputFields.length === 0) return;
1953
+ console.log(" Output array shape (declared schema):");
1954
+ for (const field of outputFields.slice(0, 60)) {
1955
+ const name = String(field.name);
1956
+ const type = stringField2(field, "type") || "unknown";
1957
+ const itemBounds = arrayItemBoundsSuffix(field);
1958
+ console.log(` - ${name}: ${type}${itemBounds}`);
1959
+ }
1960
+ if (outputFields.length > 60) {
1961
+ console.log(` - \u2026 ${outputFields.length - 60} more schema fields`);
1962
+ }
1963
+ }
1964
+ function canonicalToolJsonSchema(inputSchema) {
1965
+ return isRecord(inputSchema.jsonSchema) ? inputSchema.jsonSchema : inputSchema;
1966
+ }
1967
+ function declaredToolJsonSchema(inputSchema) {
1968
+ if (isRecord(inputSchema.jsonSchema)) {
1969
+ return inputSchema.jsonSchema;
1970
+ }
1971
+ return Array.isArray(inputSchema.fields) ? null : inputSchema;
1972
+ }
1973
+ function publicToolInputSchemaForDescribe(inputSchema) {
1974
+ const exposesProviderSpend = (description) => {
1975
+ const withoutDeeplineCredits = description.replace(
1976
+ /\bdeepline(?:-facing)?\s+credits?\b/gi,
1977
+ ""
1978
+ );
1979
+ return /\bcredits?\b/i.test(withoutDeeplineCredits) || /\bprovider\s+(?:cost|spend|price|pricing|usage)\b/i.test(
1980
+ withoutDeeplineCredits
1981
+ ) || /\b(?:costs?|charges?|priced at)\s+[$€£]\s*\d/i.test(
1982
+ withoutDeeplineCredits
1983
+ ) || /\b(?:costs?|charges?|priced at)\s+\d+(?:\.\d+)?\s*(?:usd|eur|gbp)\b/i.test(
1984
+ withoutDeeplineCredits
1985
+ ) || /\battribute-priced\b/i.test(withoutDeeplineCredits) || /\b(?:cost|price|pricing)\s+(?:grows?|increases?|scales?|varies?)\b/i.test(
1986
+ withoutDeeplineCredits
1987
+ ) || /\b(?:will be|are|is|be)\s+(?:billed|charged)\b/i.test(
1988
+ withoutDeeplineCredits
1989
+ ) || /\b(?:additional|extra)\s+charges?\b/i.test(withoutDeeplineCredits) || /\bcharg(?:e|ed)\s+(?:double|per)\b/i.test(withoutDeeplineCredits) || /\bpricing page\b/i.test(withoutDeeplineCredits);
1990
+ };
1991
+ const stripDescriptions = (value) => {
1992
+ if (Array.isArray(value)) return value.map(stripDescriptions);
1993
+ if (!isRecord(value)) return value;
1994
+ return Object.fromEntries(
1995
+ Object.entries(value).flatMap(([key, nested]) => {
1996
+ if (key === "description" && typeof nested === "string" && exposesProviderSpend(nested)) {
1997
+ return [];
1998
+ }
1999
+ return [[key, stripDescriptions(nested)]];
2000
+ })
2001
+ );
2002
+ };
2003
+ return stripDescriptions(inputSchema);
2004
+ }
2005
+ function recursiveToolInputFieldsForDisplay(inputSchema) {
2006
+ const root = canonicalToolJsonSchema(inputSchema);
2007
+ const fields = /* @__PURE__ */ new Map();
2008
+ const schemasById = /* @__PURE__ */ new Map();
2009
+ const collectSchemaIds = (value) => {
2010
+ if (Array.isArray(value)) {
2011
+ for (const item of value) collectSchemaIds(item);
2012
+ return;
2013
+ }
2014
+ if (!isRecord(value)) return;
2015
+ if (typeof value.$id === "string" && value.$id.trim()) {
2016
+ schemasById.set(value.$id.trim(), value);
2017
+ }
2018
+ for (const nested of Object.values(value)) collectSchemaIds(nested);
2019
+ };
2020
+ collectSchemaIds(root);
2021
+ const resolveRef = (schema) => {
2022
+ const ref = typeof schema.$ref === "string" ? schema.$ref : "";
2023
+ if (!ref.startsWith("#/")) return _nullishCoalesce(schemasById.get(ref), () => ( schema));
2024
+ let current = root;
2025
+ for (const rawSegment of ref.slice(2).split("/")) {
2026
+ const segment = rawSegment.replace(/~1/g, "/").replace(/~0/g, "~");
2027
+ if (!isRecord(current)) return schema;
2028
+ current = current[segment];
2029
+ }
2030
+ return isRecord(current) ? current : schema;
2031
+ };
2032
+ const addField = (field) => {
2033
+ const name = typeof field.name === "string" ? field.name : "";
2034
+ if (!name) return;
2035
+ const existing = fields.get(name);
2036
+ if (!existing || existing.type === "unknown") {
2037
+ fields.set(name, field);
2038
+ }
2039
+ };
2040
+ const visit = (unresolvedSchema, path, required, activeRefs = /* @__PURE__ */ new Set()) => {
2041
+ const ref = typeof unresolvedSchema.$ref === "string" ? unresolvedSchema.$ref : "";
2042
+ if (ref && activeRefs.has(ref)) return;
2043
+ const schema = resolveRef(unresolvedSchema);
2044
+ const nextActiveRefs = ref ? /* @__PURE__ */ new Set([...activeRefs, ref]) : activeRefs;
2045
+ const type = Array.isArray(schema.type) ? schema.type.map(String).join("|") : typeof schema.type === "string" ? schema.type : isRecord(schema.properties) ? "object" : schema.items ? "array" : "unknown";
2046
+ if (path) {
2047
+ addField({
2048
+ name: path,
2049
+ type,
2050
+ required,
2051
+ description: schema.description,
2052
+ ...Array.isArray(schema.enum) ? { enum: schema.enum } : {},
2053
+ ...isRecord(schema.items) ? { items: schema.items } : {},
2054
+ ...typeof schema.minItems === "number" ? { minItems: schema.minItems } : {},
2055
+ ...typeof schema.maxItems === "number" ? { maxItems: schema.maxItems } : {},
2056
+ ...Object.prototype.hasOwnProperty.call(schema, "default") ? { default: schema.default } : {}
2057
+ });
2058
+ }
2059
+ const properties = isRecord(schema.properties) ? schema.properties : {};
2060
+ const requiredNames = new Set(
2061
+ Array.isArray(schema.required) ? schema.required.map(String) : []
2062
+ );
2063
+ for (const [name, value] of Object.entries(properties)) {
2064
+ if (!isRecord(value)) continue;
2065
+ visit(
2066
+ value,
2067
+ path ? `${path}.${name}` : name,
2068
+ requiredNames.has(name),
2069
+ nextActiveRefs
2070
+ );
2071
+ }
2072
+ if (isRecord(schema.items)) {
2073
+ visit(schema.items, `${path}[]`, false, nextActiveRefs);
2074
+ }
2075
+ for (const keyword of ["anyOf", "oneOf", "allOf"]) {
2076
+ const branches = Array.isArray(schema[keyword]) ? schema[keyword] : [];
2077
+ for (const branch of branches) {
2078
+ if (isRecord(branch)) {
2079
+ visit(branch, path, required, nextActiveRefs);
2080
+ }
2081
+ }
2082
+ }
2083
+ };
2084
+ visit(root, "", false);
2085
+ return fields.size ? [...fields.values()] : toolInputFieldsForDisplay(inputSchema);
2086
+ }
2087
+ function inputFieldJsonForDescribe(field) {
2088
+ const publicItems = isRecord(field.items) ? publicToolInputSchemaForDescribe({ items: field.items }).items : void 0;
2089
+ return {
2090
+ name: field.name,
2091
+ type: _nullishCoalesce(field.type, () => ( "unknown")),
2092
+ required: Boolean(field.required),
2093
+ ...field.description ? { description: field.description } : {},
2094
+ ...isRecord(publicItems) ? { items: publicItems } : {},
2095
+ ...typeof field.minItems === "number" ? { minItems: field.minItems } : {},
2096
+ ...typeof field.maxItems === "number" ? { maxItems: field.maxItems } : {},
2097
+ ...Object.prototype.hasOwnProperty.call(field, "default") ? { default: field.default } : {}
2098
+ };
2099
+ }
2100
+ function arrayItemBoundsSuffix(field) {
2101
+ const itemSchema = isRecord(field.items) ? field.items : null;
2102
+ const itemType = itemSchema ? typeof itemSchema.type === "string" ? itemSchema.type : isRecord(itemSchema.properties) ? "object" : "unknown" : null;
2103
+ const itemEnum = Array.isArray(_optionalChain([itemSchema, 'optionalAccess', _16 => _16.enum])) ? ` enum=${itemSchema.enum.map(String).join("|")}` : "";
2104
+ const itemTypeSuffix = itemType && itemType !== "unknown" ? ` items=${itemType}${itemEnum}` : "";
2105
+ const minItems = typeof field.minItems === "number" && Number.isFinite(field.minItems) ? field.minItems : null;
2106
+ const maxItems = typeof field.maxItems === "number" && Number.isFinite(field.maxItems) ? field.maxItems : null;
2107
+ if (minItems !== null && maxItems !== null) {
2108
+ return itemTypeSuffix ? `${itemTypeSuffix} minItems=${minItems} maxItems=${maxItems}` : ` items=${minItems}..${maxItems}`;
2109
+ }
2110
+ if (minItems !== null) return `${itemTypeSuffix} minItems=${minItems}`;
2111
+ if (maxItems !== null) return `${itemTypeSuffix} maxItems=${maxItems}`;
2112
+ return itemTypeSuffix;
2113
+ }
2114
+ function printToolExecutionHints(value) {
2115
+ const batchCapabilityRecord = recordField(
2116
+ isRecord(value) ? value : {},
2117
+ "batchCapability",
2118
+ "batch_capability"
2119
+ );
2120
+ const batchCapability = Object.keys(batchCapabilityRecord).length > 0 ? batchCapabilityRecord : null;
2121
+ const executionMetadata = recordField(
2122
+ isRecord(value) ? value : {},
2123
+ "executionMetadata",
2124
+ "execution_metadata"
2125
+ );
2126
+ if (batchCapability) {
2127
+ const status = stringField2(batchCapability, "status") || "unknown";
2128
+ const surface = stringField2(batchCapability, "surface");
2129
+ const operation = stringField2(
2130
+ batchCapability,
2131
+ "batchOperation",
2132
+ "batch_operation"
2133
+ );
2134
+ const maxBatchSize = numberField2(
2135
+ batchCapability,
2136
+ "maxBatchSize",
2137
+ "max_batch_size"
2138
+ );
2139
+ const notes = stringField2(batchCapability, "notes");
2140
+ console.log("");
2141
+ console.log("Batching:");
2142
+ console.log(`- Catalog status: ${status}${surface ? ` (${surface})` : ""}`);
2143
+ if (operation) console.log(`- Batch operation: ${operation}`);
2144
+ if (maxBatchSize !== null) {
2145
+ console.log(`- Maximum batch size: ${maxBatchSize} items`);
2146
+ }
2147
+ if (status === "compiled") {
2148
+ console.log(
2149
+ "- Compatible per-row Play calls can coalesce; separate tools execute requests do not coalesce."
2150
+ );
2151
+ } else if (surface !== "docs") {
2152
+ console.log(
2153
+ "- Play does not automatically coalesce per-row calls for this operation; send a native batch as one request when its input schema supports one."
2154
+ );
2155
+ }
2156
+ if (notes) console.log(`- Details: ${notes}`);
2157
+ }
2158
+ const configuredRateLimits = arrayField2(
2159
+ executionMetadata,
2160
+ "configuredRateLimits",
2161
+ "configured_rate_limits"
2162
+ ).filter(isRecord);
2163
+ if (configuredRateLimits.length > 0) {
2164
+ console.log("");
2165
+ console.log(
2166
+ "Configured Deepline pacing (guidance, not a guaranteed provider quota):"
2167
+ );
2168
+ for (const limit of configuredRateLimits) {
2169
+ const requests = numberField2(limit, "requestsPerWindow");
2170
+ const windowMs = numberField2(limit, "windowMs");
2171
+ if (requests === null || windowMs === null) continue;
2172
+ const usage = stringField2(limit, "usage") || "unknown";
2173
+ 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;
2174
+ const explicitMaxConcurrency = numberField2(
2175
+ limit,
2176
+ "explicitMaxConcurrency",
2177
+ "explicit_max_concurrency"
2178
+ );
2179
+ const concurrencyText = explicitMaxConcurrency === null ? "no explicit concurrency limit" : `explicit concurrency limit ${explicitMaxConcurrency}`;
2180
+ console.log(
2181
+ `- ${requests} requests per ${formatRateWindow(windowMs)} (${usageText}; ${concurrencyText})`
2182
+ );
2183
+ }
2184
+ }
2185
+ const queueHint = recordField(executionMetadata, "queueHint", "queue_hint");
2186
+ const requestsPerSecondHint = numberField2(
2187
+ queueHint,
2188
+ "requestsPerSecondHint",
2189
+ "requests_per_second_hint"
2190
+ );
2191
+ const derivedConcurrency = numberField2(
2192
+ queueHint,
2193
+ "derivedConcurrency",
2194
+ "derived_concurrency"
2195
+ );
2196
+ if (requestsPerSecondHint !== null && requestsPerSecondHint > 0 && derivedConcurrency !== null) {
2197
+ console.log(
2198
+ `Derived runtime queue hint: ${requestsPerSecondHint} requests/second; ${derivedConcurrency} derived concurrency. This is not an observed provider concurrency limit.`
2199
+ );
2200
+ }
2201
+ }
2202
+ function formatRateWindow(windowMs) {
2203
+ if (windowMs === 1e3) return "second";
2204
+ if (windowMs === 6e4) return "minute";
2205
+ if (windowMs === 36e5) return "hour";
2206
+ return `${windowMs}ms`;
2207
+ }
2208
+ function samplePayload(samples, key) {
2209
+ const entry = samples[key];
2210
+ if (!isRecord(entry)) return void 0;
2211
+ return Object.prototype.hasOwnProperty.call(entry, "payload") ? entry.payload : entry;
2212
+ }
2213
+ function commandEnvelopeFromRawResponse(rawResponse) {
2214
+ return isRecord(rawResponse) ? { ...rawResponse } : { status: "completed", result: rawResponse };
2215
+ }
2216
+ function toolExecuteExitCode(envelope) {
2217
+ return envelope.status === "failed" || envelope.ok === false ? 1 : 0;
2218
+ }
2219
+ function extractToolExecutionWarningMessages(rawResponse) {
2220
+ if (!isRecord(rawResponse)) return [];
2221
+ const candidates = [
2222
+ recordField(recordField(rawResponse, "toolResponse"), "meta"),
2223
+ recordField(
2224
+ recordField(recordField(rawResponse, "toolResponse"), "raw"),
2225
+ "meta"
2226
+ ),
2227
+ recordField(rawResponse, "meta"),
2228
+ recordField(recordField(rawResponse, "result"), "meta")
2229
+ ];
2230
+ const messages = [];
2231
+ for (const candidate of candidates) {
2232
+ const warnings = _optionalChain([candidate, 'optionalAccess', _17 => _17.warnings]);
2233
+ if (!Array.isArray(warnings)) continue;
2234
+ for (const warning of warnings) {
2235
+ if (typeof warning === "string" && warning.trim()) {
2236
+ messages.push(warning.trim());
2237
+ } else if (isRecord(warning)) {
2238
+ const message = stringField2(warning, "message");
2239
+ if (message) messages.push(message);
2240
+ }
2241
+ }
2242
+ }
2243
+ return [...new Set(messages)];
2244
+ }
2245
+ function apifySyncRecoveryNext(rawResponse) {
2246
+ if (!isRecord(rawResponse) || rawResponse.status !== "running") return null;
2247
+ const toolResponse = recordField(rawResponse, "toolResponse");
2248
+ const raw = recordField(toolResponse, "raw");
2249
+ if (raw.state !== "awaiting_apify") return null;
2250
+ const next = recordField(raw, "next");
2251
+ const getActorRun = recordField(next, "getActorRun");
2252
+ const getActorRunTool = stringField2(getActorRun, "tool");
2253
+ const getActorRunPayload = recordField(getActorRun, "payload");
2254
+ if (!getActorRunTool || Object.keys(getActorRunPayload).length === 0) {
2255
+ return null;
2256
+ }
2257
+ const getDatasetItems = recordField(next, "getDatasetItems");
2258
+ const getDatasetItemsTool = stringField2(getDatasetItems, "tool");
2259
+ const getDatasetItemsPayload = recordField(getDatasetItems, "payload");
2260
+ return {
2261
+ getActorRun: `deepline tools execute ${getActorRunTool} --input ${shellQuote(JSON.stringify(getActorRunPayload))} --json`,
2262
+ ...getDatasetItemsTool && Object.keys(getDatasetItemsPayload).length > 0 ? {
2263
+ getDatasetItems: `deepline tools execute ${getDatasetItemsTool} --input ${shellQuote(JSON.stringify(getDatasetItemsPayload))} --json`
2264
+ } : {}
2265
+ };
2266
+ }
2267
+ function listExtractorPathsFromUsageGuidance(tool) {
2268
+ const toolExecutionResult = _optionalChain([tool, 'access', _18 => _18.usageGuidance, 'optionalAccess', _19 => _19.toolExecutionResult]);
2269
+ const extractedLists = Array.isArray(_optionalChain([toolExecutionResult, 'optionalAccess', _20 => _20.extractedLists])) ? toolExecutionResult.extractedLists : isRecord(_optionalChain([toolExecutionResult, 'optionalAccess', _21 => _21.extractedLists])) ? Object.values(toolExecutionResult.extractedLists) : [];
2270
+ return extractedLists.flatMap((entry) => {
2271
+ const paths = _nullishCoalesce(_optionalChain([entry, 'access', _22 => _22.details, 'optionalAccess', _23 => _23.candidatePaths]), () => ( _optionalChain([entry, 'access', _24 => _24.details, 'optionalAccess', _25 => _25.rawToolOutputPaths])));
2272
+ if (!Array.isArray(paths)) return [];
2273
+ return paths.map(
2274
+ (path) => path.trim().replace(/^toolExecutionResult\.toolResponse\.raw\.?/, "").replace(/^toolExecutionResult\.toolOutput\.raw\.?/, "").replace(/^\./, "")
2275
+ ).filter(Boolean);
2276
+ });
2277
+ }
2278
+ function formatDecimal(value) {
2279
+ const text = value.toFixed(12).replace(/0+$/, "").replace(/\.$/, "");
2280
+ return text || "0";
2281
+ }
2282
+ function formatUsd(value) {
2283
+ return `$${formatDecimal(value)}`;
2284
+ }
2285
+ function isRecord(value) {
2286
+ return Boolean(value && typeof value === "object" && !Array.isArray(value));
2287
+ }
2288
+ function stringField2(source, ...keys) {
2289
+ for (const key of keys) {
2290
+ const value = source[key];
2291
+ if (typeof value === "string" && value.trim()) return value.trim();
2292
+ }
2293
+ return "";
2294
+ }
2295
+ function numberField2(source, ...keys) {
2296
+ for (const key of keys) {
2297
+ const value = source[key];
2298
+ if (typeof value === "number" && Number.isFinite(value)) return value;
2299
+ }
2300
+ return null;
2301
+ }
2302
+ function arrayField2(source, ...keys) {
2303
+ for (const key of keys) {
2304
+ const value = source[key];
2305
+ if (Array.isArray(value)) return value;
2306
+ }
2307
+ return [];
2308
+ }
2309
+ function recordField(source, ...keys) {
2310
+ for (const key of keys) {
2311
+ const value = source[key];
2312
+ if (isRecord(value)) return value;
2313
+ }
2314
+ return {};
2315
+ }
2316
+ function normalizeOutputFormat(raw) {
2317
+ switch ((raw || "auto").trim().toLowerCase()) {
2318
+ case "auto":
2319
+ return "auto";
2320
+ case "csv":
2321
+ return "csv";
2322
+ case "csv_file":
2323
+ return "csv_file";
2324
+ case "json":
2325
+ return "json";
2326
+ case "json_file":
2327
+ return "json_file";
2328
+ default:
2329
+ throw new Error(`Invalid value for --output-format: ${raw}`);
2330
+ }
2331
+ }
2332
+ function resolveAtFilePath(rawPath) {
2333
+ const trimmed = rawPath.trim();
2334
+ const resolved = _path.resolve.call(void 0, trimmed);
2335
+ if (_fs.existsSync.call(void 0, resolved)) return resolved;
2336
+ if (process.platform !== "win32" && trimmed.includes("\\")) {
2337
+ const normalized = _path.resolve.call(void 0, trimmed.replace(/\\/g, "/"));
2338
+ if (_fs.existsSync.call(void 0, normalized)) return normalized;
2339
+ }
2340
+ return resolved;
2341
+ }
2342
+ function readJsonArgument(raw, flagName) {
2343
+ if (!raw.startsWith("@")) return raw.replace(/^\uFEFF/, "");
2344
+ const filePath = raw.slice(1).trim();
2345
+ if (!filePath) {
2346
+ throw new Error(`Invalid ${flagName} value: empty @file path.`);
2347
+ }
2348
+ try {
2349
+ return _fs.readFileSync.call(void 0, resolveAtFilePath(filePath), "utf8").replace(
2350
+ /^\uFEFF/,
2351
+ ""
2352
+ );
2353
+ } catch (error) {
2354
+ const message = error instanceof Error ? error.message : String(error);
2355
+ throw new Error(
2356
+ `Failed to read ${flagName} file '${filePath}': ${message}`
2357
+ );
2358
+ }
2359
+ }
2360
+ function invalidJsonError(flagName, message) {
2361
+ const error = new Error(
2362
+ `Invalid JSON in ${flagName}: ${message}`
2363
+ );
2364
+ error.code = "INVALID_JSON";
2365
+ return error;
2366
+ }
2367
+ function parseJsonObjectArgument(raw, flagName) {
2368
+ let parsed;
2369
+ try {
2370
+ parsed = JSON.parse(readJsonArgument(raw, flagName));
2371
+ } catch (error) {
2372
+ const message = error instanceof Error ? error.message : String(error);
2373
+ if (message.startsWith("Failed to read ") || message.startsWith("Invalid ")) {
2374
+ throw error;
2375
+ }
2376
+ throw invalidJsonError(flagName, message);
2377
+ }
2378
+ if (!isRecord(parsed)) {
2379
+ throw invalidJsonError(flagName, "expected an object.");
2380
+ }
2381
+ return parsed;
2382
+ }
2383
+ function parseExecuteOptions(args) {
2384
+ const toolId = args[0];
2385
+ if (!toolId) {
2386
+ throw new Error(
2387
+ `Usage: deepline tools execute <toolId> [--param key=value ...] [--input '{"k":"v"}'] [--timeout <duration>] [--recover | --idempotency-key <key>] [--recovery-timeout-ms <ms>] [--out rows.csv] [--output-format auto|csv|csv_file|json|json_file] [--no-preview]`
2388
+ );
2389
+ }
2390
+ const params = {};
2391
+ let outputFormat = "auto";
2392
+ let noPreview = false;
2393
+ let outPath = null;
2394
+ let timeoutMs;
2395
+ let idempotencyKey;
2396
+ let recover = false;
2397
+ let recoveryTimeoutMs;
2398
+ for (let index = 1; index < args.length; index += 1) {
2399
+ const arg = args[index];
2400
+ if ((arg === "--param" || arg === "-p") && args[index + 1]) {
2401
+ const kv = args[++index];
2402
+ const eqIdx = kv.indexOf("=");
2403
+ if (eqIdx > 0) params[kv.slice(0, eqIdx)] = kv.slice(eqIdx + 1);
2404
+ continue;
2405
+ }
2406
+ if (arg === "--json") {
2407
+ const next = args[index + 1];
2408
+ outputFormat = "json";
2409
+ if (next && !next.startsWith("--")) {
2410
+ Object.assign(
2411
+ params,
2412
+ parseJsonObjectArgument(args[++index], "--json")
2413
+ );
2414
+ }
2415
+ continue;
2416
+ }
2417
+ if ((arg === "--input" || arg === "--payload") && args[index + 1]) {
2418
+ Object.assign(params, parseJsonObjectArgument(args[++index], arg));
2419
+ continue;
2420
+ }
2421
+ if (arg === "--timeout" && args[index + 1]) {
2422
+ timeoutMs = parseToolExecuteTimeout(args[++index]);
2423
+ continue;
2424
+ }
2425
+ if (arg === "--output-format" && args[index + 1]) {
2426
+ outputFormat = normalizeOutputFormat(args[++index]);
2427
+ continue;
2428
+ }
2429
+ if (arg === "--no-preview") {
2430
+ noPreview = true;
2431
+ continue;
2432
+ }
2433
+ if (arg === "--idempotency-key" && args[index + 1]) {
2434
+ idempotencyKey = args[++index];
2435
+ continue;
2436
+ }
2437
+ if (arg === "--recover") {
2438
+ recover = true;
2439
+ continue;
2440
+ }
2441
+ if (arg === "--recovery-timeout-ms" && args[index + 1]) {
2442
+ const parsed = Number(args[++index]);
2443
+ if (!Number.isFinite(parsed) || parsed < 0) {
2444
+ throw new Error("--recovery-timeout-ms must be a non-negative number.");
2445
+ }
2446
+ recoveryTimeoutMs = parsed;
2447
+ continue;
2448
+ }
2449
+ if ((arg === "--out" || arg === "-o") && args[index + 1]) {
2450
+ outPath = _path.resolve.call(void 0, args[++index]);
2451
+ continue;
2452
+ }
2453
+ throw new Error(`Unknown option: ${arg}`);
2454
+ }
2455
+ return {
2456
+ toolId,
2457
+ params,
2458
+ outputFormat,
2459
+ noPreview,
2460
+ outPath,
2461
+ timeoutMs,
2462
+ idempotencyKey,
2463
+ recover,
2464
+ recoveryTimeoutMs
2465
+ };
2466
+ }
2467
+ function parseToolExecuteTimeout(raw) {
2468
+ const match = /^(\d+)(ms|s|m|h)?$/i.exec(raw.trim());
2469
+ if (!match) {
2470
+ throw new Error(
2471
+ "--timeout must be a duration like 500ms, 90s, 10m, or 1h (a bare number is seconds)."
2472
+ );
2473
+ }
2474
+ const value = Number(match[1]);
2475
+ const unit = (_nullishCoalesce(match[2], () => ( "s"))).toLowerCase();
2476
+ const factor = unit === "ms" ? 1 : unit === "s" ? 1e3 : unit === "m" ? 6e4 : 36e5;
2477
+ const timeoutMs = value * factor;
2478
+ if (!Number.isSafeInteger(timeoutMs) || timeoutMs < 1 || timeoutMs > 2147483647) {
2479
+ throw new Error(
2480
+ "--timeout must be between 1ms and 2147483647ms (24d 20h 31m 23s)."
2481
+ );
2482
+ }
2483
+ return timeoutMs;
2484
+ }
2485
+ function safeFileStem(value) {
2486
+ return value.trim().replace(/[^a-zA-Z0-9_-]+/g, "-").replace(/^-+|-+$/g, "").slice(0, 64) || "tool";
2487
+ }
2488
+ function shellQuote(value) {
2489
+ return `'${value.replace(/'/g, `'\\''`)}'`;
2490
+ }
2491
+ function powerShellQuote(value) {
2492
+ return `'${value.replace(/'/g, "''")}'`;
2493
+ }
2494
+ function starterScriptJson(script) {
2495
+ return {
2496
+ path: script.path,
2497
+ sourceCode: script.sourceCode,
2498
+ projectDir: script.projectDir,
2499
+ copyToProject: {
2500
+ macosLinux: script.macCopyCommand,
2501
+ windowsPowerShell: script.windowsCopyCommand
2502
+ }
2503
+ };
2504
+ }
2505
+ function seedToolListScript(input) {
2506
+ const stem = safeFileStem(input.toolId);
2507
+ const fileName = `${stem}-workflow-seed-${Date.now()}.play.ts`;
2508
+ const scriptDir = _fs.mkdtempSync.call(void 0, _path.join.call(void 0, _os.tmpdir.call(void 0, ), "deepline-workflow-seed-"));
2509
+ _fs.chmodSync.call(void 0, scriptDir, 448);
2510
+ const scriptPath = _path.join.call(void 0, scriptDir, fileName);
2511
+ const projectDir = `deepline/projects/${stem}-workflow`;
2512
+ const playName = `${stem}-workflow`;
2513
+ const sampleRows = input.rows.length > 0 ? `${JSON.stringify(input.rows.slice(0, 2)).replace(/\]$/, "")}, ...]` : "[]";
2514
+ const columns = Object.keys(_nullishCoalesce(input.rows[0], () => ( {}))).join(", ");
2515
+ const rowKey = Object.prototype.hasOwnProperty.call(_nullishCoalesce(input.rows[0], () => ( {})), "id") ? '"id"' : "(row) => JSON.stringify(row)";
2516
+ const script = `import { definePlay } from 'deepline';
2517
+
2518
+ export default definePlay(${JSON.stringify(playName)}, async (ctx) => {
2519
+ const result = await ctx.tools.execute({
2520
+ id: ${JSON.stringify(input.toolId)},
2521
+ tool: ${JSON.stringify(input.toolId)},
2522
+ input: ${JSON.stringify(input.payload)},
2523
+ description: ${JSON.stringify(`Seed ${input.toolId} rows for workflow expansion.`)},
2524
+ });
2525
+
2526
+ const list = Object.values(result.extractedLists)[0];
2527
+ if (!list) {
2528
+ throw new Error('Expected ${input.toolId} to expose an extracted list getter.');
2529
+ }
2530
+ const rows = list.get();
2531
+ // ${sampleRows}
2532
+ // columns: ${columns}
2533
+ // extractedLists.<name>.get() returns a dataset handle for row-shaped list outputs.
2534
+ // Pass it to ctx.dataset; use rows.peek/count/materialize only for deliberate bounded inspection.
2535
+ // .withColumn('email_waterfall', (row, rowCtx) => rowCtx.runPlay('name_domain_email', 'name-and-domain-to-email', { first_name: String(row.first_name ?? ''), last_name: String(row.last_name ?? ''), domain: String(row.domain ?? '') }, { description: 'Resolve email.' }))
2536
+ // .withColumn('phone_waterfall', (row, rowCtx) => rowCtx.runPlay('contact_phone', 'contact-to-phone', { first_name: String(row.first_name ?? ''), last_name: String(row.last_name ?? ''), email: String(row.email ?? '') }, { description: 'Resolve phone.' }))
2537
+ // ctx.dataset is idempotent by dataset key + row key; reruns reuse completed rows.
2538
+ const enrichedData = await ctx
2539
+ .dataset('enriched_data', rows)
2540
+ .run({
2541
+ key: ${rowKey},
2542
+ description: 'Enrich seeded rows.',
2543
+ });
2544
+
2545
+ return {
2546
+ rows: enrichedData,
2547
+ count: await enrichedData.count(),
2548
+ };
2549
+ }, {
2550
+ description: ${JSON.stringify(`Seed ${input.toolId} rows into a Deepline workflow-ready dataset.`)},
2551
+ });
2552
+ `;
2553
+ _fs.writeFileSync.call(void 0, scriptPath, script, { encoding: "utf-8", mode: 384 });
2554
+ return {
2555
+ path: scriptPath,
2556
+ sourceCode: script,
2557
+ projectDir,
2558
+ macCopyCommand: `mkdir -p ${shellQuote(projectDir)} && cp ${shellQuote(scriptPath)} ${shellQuote(`${projectDir}/${fileName}`)}`,
2559
+ windowsCopyCommand: `New-Item -ItemType Directory -Force -Path ${powerShellQuote(projectDir.replace(/\//g, "\\"))} | Out-Null; Copy-Item -LiteralPath ${powerShellQuote(scriptPath)} -Destination ${powerShellQuote(`${projectDir.replace(/\//g, "\\")}\\${fileName}`)}`
2560
+ };
2561
+ }
2562
+ function buildToolExecuteBaseEnvelope(input) {
2563
+ const envelope = commandEnvelopeFromRawResponse(input.rawResponse);
2564
+ const guidanceLines = toolExecuteExitCode(envelope) !== 0 || input.listExpected === true && !input.listConversion ? toolGuidanceLines(input.guidance) : [];
2565
+ const warningMessages = extractToolExecutionWarningMessages(
2566
+ input.rawResponse
2567
+ );
2568
+ const apifyRecovery = apifySyncRecoveryNext(input.rawResponse);
2569
+ const summaryEntries = Object.entries(input.summary);
2570
+ const outputPreview = input.listConversion ? {
2571
+ kind: "list",
2572
+ rowCount: input.listConversion.rows.length,
2573
+ columns: Object.keys(_nullishCoalesce(input.listConversion.rows[0], () => ( {}))),
2574
+ preview: input.listConversion.rows.slice(0, 5),
2575
+ listStrategy: input.listConversion.strategy,
2576
+ listSourcePath: input.listConversion.sourcePath
2577
+ } : {
2578
+ kind: summaryEntries.length > 0 ? "object" : "raw",
2579
+ summary: input.summary
2580
+ };
2581
+ const envelopeHasCanonicalOutput = isRecord(envelope.toolResponse) && Object.prototype.hasOwnProperty.call(envelope.toolResponse, "raw");
2582
+ const envelopeHasDeclaredOutput = Object.prototype.hasOwnProperty.call(
2583
+ envelope,
2584
+ "output"
2585
+ );
2586
+ const billingLookup = typeof envelope.job_id === "string" && envelope.job_id.trim() ? `deepline billing usage --request-id ${shellQuote(envelope.job_id)} --json` : null;
2587
+ const inspectCommand = `deepline tools execute ${input.toolId} --input ${shellQuote(JSON.stringify(input.params))} --json`;
2588
+ const actions = input.listConversion ? [
2589
+ {
2590
+ label: "next",
2591
+ command: "move starter script into a project folder and expand it into a Deepline play"
2592
+ }
2593
+ ] : apifyRecovery ? [
2594
+ { label: "check Apify run", command: apifyRecovery.getActorRun },
2595
+ ...apifyRecovery.getDatasetItems ? [
2596
+ {
2597
+ label: "get Apify dataset items",
2598
+ command: apifyRecovery.getDatasetItems
2599
+ }
2600
+ ] : []
2601
+ ] : [];
2602
+ if (billingLookup) {
2603
+ actions.push({ label: "charge", command: billingLookup });
2604
+ }
2605
+ return {
2606
+ ...envelope,
2607
+ ...input.idempotencyKey ? { idempotency_key: input.idempotencyKey } : {},
2608
+ ...isRecord(input.rawResponse) && isRecord(input.rawResponse.executionRecovery) ? { execution_recovery: input.rawResponse.executionRecovery } : {},
2609
+ ...envelopeHasCanonicalOutput || envelopeHasDeclaredOutput ? { output_preview: outputPreview } : { output: outputPreview },
2610
+ ...summaryEntries.length > 0 ? { summary: input.summary } : {},
2611
+ ...warningMessages.length > 0 ? { warnings: warningMessages } : {},
2612
+ next: {
2613
+ inspect: inspectCommand,
2614
+ ...billingLookup ? { billing: billingLookup } : {},
2615
+ ..._nullishCoalesce(apifyRecovery, () => ( {})),
2616
+ ...guidanceLines.length > 0 ? { guidance: input.guidance } : {},
2617
+ 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.",
2618
+ ...input.listConversion ? {
2619
+ expandToPlay: "Use stable map and step keys so reruns are idempotent: completed rows are reused, and only missing or stale work runs again.",
2620
+ listSourcePath: _nullishCoalesce(input.listConversion.sourcePath, () => ( "auto-detected list in the CLI response preview"))
2621
+ } : {}
2622
+ },
2623
+ render: {
2624
+ sections: input.listConversion ? [
2625
+ ...warningMessages.length > 0 ? [{ title: "warnings", lines: warningMessages }] : [],
2626
+ {
2627
+ title: "output",
2628
+ lines: [
2629
+ `${input.listConversion.rows.length} row(s) extracted from ${_nullishCoalesce(input.listConversion.sourcePath, () => ( "auto-detected list"))}`,
2630
+ "paths above are observed from this execute response; use runs get and runs export to validate play output",
2631
+ `columns: ${JSON.stringify(Object.keys(_nullishCoalesce(input.listConversion.rows[0], () => ( {}))))}`,
2632
+ `preview: ${JSON.stringify(input.listConversion.rows.slice(0, 5))}`
2633
+ ]
2634
+ }
2635
+ ] : [
2636
+ ...warningMessages.length > 0 ? [{ title: "warnings", lines: warningMessages }] : [],
2637
+ {
2638
+ title: "result",
2639
+ lines: apifyRecovery ? [
2640
+ "Apify is still running. Run the follow-up command(s) below."
2641
+ ] : summaryEntries.length > 0 ? summaryEntries.map(
2642
+ ([key, value]) => `${key}=${String(value)}`
2643
+ ) : [JSON.stringify(input.rawResponse, null, 2)]
2644
+ },
2645
+ ...guidanceLines.length > 0 ? [{ title: "guidance", lines: guidanceLines }] : []
2646
+ ],
2647
+ actions
2648
+ }
2649
+ };
2650
+ }
2651
+ function buildToolExecuteRowArtifactEnvelope(input) {
2652
+ const {
2653
+ toolResponse: _toolResponse,
2654
+ result: _result,
2655
+ output: _output,
2656
+ output_preview: _outputPreview,
2657
+ render: _render,
2658
+ next: _next,
2659
+ local: _local,
2660
+ ...base
2661
+ } = input.baseEnvelope;
2662
+ void _toolResponse;
2663
+ void _result;
2664
+ void _output;
2665
+ void _outputPreview;
2666
+ void _render;
2667
+ void _next;
2668
+ void _local;
2669
+ const billingLookup = isRecord(input.baseEnvelope.next) && typeof input.baseEnvelope.next.billing === "string" ? input.baseEnvelope.next.billing : null;
2670
+ return {
2671
+ ...base,
2672
+ status: typeof base.status === "string" ? base.status : "completed",
2673
+ output_preview: {
2674
+ kind: "list",
2675
+ rowCount: input.rowOutput.rowCount,
2676
+ columns: input.rowOutput.columns,
2677
+ preview: input.rowOutput.previewRows,
2678
+ listStrategy: input.rowOutput.strategy,
2679
+ listSourcePath: input.rowOutput.sourcePath
2680
+ },
2681
+ csv_path: input.csv.path,
2682
+ row_count: input.csv.rowCount,
2683
+ row_count_returned: input.csv.rowCount,
2684
+ columns: input.csv.columns,
2685
+ extracted_csv: input.csv.path,
2686
+ extracted_csv_rows: input.csv.rowCount,
2687
+ extracted_csv_columns: input.csv.columns,
2688
+ preview: input.csv.preview,
2689
+ list_strategy: input.rowOutput.strategy,
2690
+ list_source_path: input.rowOutput.sourcePath,
2691
+ summary: input.summary,
2692
+ local: {
2693
+ extracted_csv: input.csv.path,
2694
+ extracted_csv_rows: input.csv.rowCount,
2695
+ extracted_csv_columns: input.csv.columns,
2696
+ preview: input.csv.preview,
2697
+ starter_script: input.seededScript.path,
2698
+ project_dir: input.seededScript.projectDir,
2699
+ copy_to_project: {
2700
+ macos_linux: input.seededScript.macCopyCommand,
2701
+ windows_powershell: input.seededScript.windowsCopyCommand
2702
+ }
2703
+ },
2704
+ starter_script: input.seededScript.path,
2705
+ project_dir: input.seededScript.projectDir,
2706
+ copy_to_project: {
2707
+ macos_linux: input.seededScript.macCopyCommand,
2708
+ windows_powershell: input.seededScript.windowsCopyCommand
2709
+ },
2710
+ next: {
2711
+ inspect: "Re-run with --json only when you need the raw provider/tool response.",
2712
+ ...billingLookup ? { billing: billingLookup } : {},
2713
+ listSourcePath: input.rowOutput.sourcePath,
2714
+ expandToPlay: "Use stable map and step keys so reruns are idempotent: completed rows are reused, and only missing or stale work runs again."
2715
+ },
2716
+ render: {
2717
+ sections: [
2718
+ {
2719
+ title: `${input.csv.path} (${input.csv.rowCount} rows)`,
2720
+ lines: [
2721
+ ...input.csv.columns.length > 0 ? [`columns: ${JSON.stringify(input.csv.columns)}`] : [],
2722
+ ...Object.keys(input.summary).length > 0 ? [
2723
+ `summary: ${Object.entries(input.summary).map(([key, value]) => `${key}=${String(value)}`).join(", ")}`
2724
+ ] : [],
2725
+ `preview: ${JSON.stringify(input.rowOutput.previewRows)}`,
2726
+ `starter script: ${input.seededScript.path}`
2727
+ ]
2728
+ }
2729
+ ],
2730
+ actions: [
2731
+ ...billingLookup ? [{ label: "charge", command: billingLookup }] : [],
2732
+ {
2733
+ label: "next",
2734
+ command: "Move the script into a project folder and expand it into a Deepline play. Use stable map and step keys so reruns are idempotent: completed rows are reused, and only missing or stale work runs again."
2735
+ },
2736
+ {
2737
+ label: "macOS/Linux",
2738
+ command: input.seededScript.macCopyCommand
2739
+ },
2740
+ {
2741
+ label: "Windows PowerShell",
2742
+ command: input.seededScript.windowsCopyCommand
2743
+ }
2744
+ ]
2745
+ }
2746
+ };
2747
+ }
2748
+ async function executeTool(args) {
2749
+ let parsed;
2750
+ try {
2751
+ parsed = parseExecuteOptions(args);
2752
+ } catch (error) {
2753
+ if (_chunkF35VOIQLjs.argsWantJson.call(void 0, args)) {
2754
+ _chunkF35VOIQLjs.printJsonError.call(void 0, error);
2755
+ } else {
2756
+ console.error(error instanceof Error ? error.message : String(error));
2757
+ }
2758
+ return 1;
2759
+ }
2760
+ const client = new (0, _chunk2S5Y3TZPjs.DeeplineClient)();
2761
+ let metadata;
2762
+ try {
2763
+ metadata = await client.getTool(parsed.toolId);
2764
+ } catch (error) {
2765
+ if (isMissingToolMetadataError(error)) {
2766
+ const play = await findPlayForToolId(client, parsed.toolId);
2767
+ if (play) {
2768
+ if (_chunkF35VOIQLjs.argsWantJson.call(void 0, args)) {
2769
+ _chunkF35VOIQLjs.printJsonError.call(void 0,
2770
+ new Error(playAliasToolErrorMessage(parsed.toolId, play))
2771
+ );
2772
+ } else {
2773
+ printPlayAliasToolError(parsed.toolId, play);
2774
+ }
2775
+ return 2;
2776
+ }
2777
+ }
2778
+ throw error;
2779
+ }
2780
+ if (isPlayLikeTool(metadata)) {
2781
+ if (_chunkF35VOIQLjs.argsWantJson.call(void 0, args)) {
2782
+ _chunkF35VOIQLjs.printJsonError.call(void 0,
2783
+ new Error(
2784
+ playLikeToolExecuteErrorMessage(
2785
+ parsed.toolId,
2786
+ metadata
2787
+ )
2788
+ )
2789
+ );
2790
+ } else {
2791
+ printPlayLikeToolExecuteError(
2792
+ parsed.toolId,
2793
+ metadata
2794
+ );
2795
+ }
2796
+ return 2;
2797
+ }
2798
+ const responseIntent = parsed.outPath || parsed.outputFormat === "csv" || parsed.outputFormat === "csv_file" ? "row_artifact" : "raw";
2799
+ const recovery = ToolCallRecovery.open({
2800
+ toolId: parsed.toolId,
2801
+ params: parsed.params,
2802
+ responseIntent,
2803
+ recover: parsed.recover,
2804
+ idempotencyKey: parsed.idempotencyKey
2805
+ });
2806
+ const { idempotencyKey } = recovery;
2807
+ if (idempotencyKey) {
2808
+ console.error(`Tool execution recovery key: ${idempotencyKey}`);
2809
+ }
2810
+ const rawResponse = await client.executeTool(parsed.toolId, parsed.params, {
2811
+ ...parsed.timeoutMs !== void 0 ? { timeout: parsed.timeoutMs } : {},
2812
+ ..._optionalChain([metadata, 'access', _26 => _26.executionMetadata, 'optionalAccess', _27 => _27.retrySafeTransientHttp]) === true ? { maxRetries: 2, retryApiErrors: true } : {},
2813
+ responseIntent,
2814
+ ...idempotencyKey ? { idempotencyKey } : {},
2815
+ ...parsed.recoveryTimeoutMs !== void 0 ? { recoveryTimeoutMs: parsed.recoveryTimeoutMs } : {},
2816
+ searchRef: _chunkWQICC2B3js.recentSearchRef.call(void 0, )
2817
+ }).catch((error) => {
2818
+ const guidanceLines = toolGuidanceLines(metadata.guidance);
2819
+ if (guidanceLines.length > 0) {
2820
+ if (args.includes("--json") && error instanceof Error) {
2821
+ Object.assign(error, { guidance: metadata.guidance });
2822
+ } else {
2823
+ console.error(
2824
+ [`Guidance for ${parsed.toolId}:`, ...guidanceLines].join("\n")
2825
+ );
2826
+ }
2827
+ }
2828
+ throw error;
2829
+ });
2830
+ const listExtractorPaths = listExtractorPathsFromUsageGuidance(metadata);
2831
+ const listConversion = _chunkNXDRDJ4Kjs.tryConvertToList.call(void 0, rawResponse, { listExtractorPaths });
2832
+ const summary = _chunkNXDRDJ4Kjs.extractSummaryFields.call(void 0, rawResponse);
2833
+ const baseEnvelope = buildToolExecuteBaseEnvelope({
2834
+ toolId: parsed.toolId,
2835
+ params: parsed.params,
2836
+ ...idempotencyKey ? { idempotencyKey } : {},
2837
+ rawResponse,
2838
+ listConversion,
2839
+ summary,
2840
+ guidance: metadata.guidance,
2841
+ listExpected: listExtractorPaths.length > 0
2842
+ });
2843
+ const executeExitCode = toolExecuteExitCode(baseEnvelope);
2844
+ const delivered = (() => {
2845
+ if (!parsed.outPath && (parsed.outputFormat === "json" || parsed.outputFormat === "auto" && _chunkF35VOIQLjs.shouldEmitJson.call(void 0, ))) {
2846
+ _chunkF35VOIQLjs.printCommandEnvelope.call(void 0, baseEnvelope, { json: true });
2847
+ return true;
2848
+ }
2849
+ if (parsed.outputFormat === "json_file") {
2850
+ const jsonPath = _chunkNXDRDJ4Kjs.writeJsonOutputFile.call(void 0,
2851
+ rawResponse,
2852
+ `payload_${parsed.toolId}`
2853
+ );
2854
+ _chunkF35VOIQLjs.printCommandEnvelope.call(void 0,
2855
+ {
2856
+ ...baseEnvelope,
2857
+ local: {
2858
+ ...isRecord(baseEnvelope.local) ? baseEnvelope.local : {},
2859
+ payload_file: jsonPath
2860
+ }
2861
+ },
2862
+ { json: true }
2863
+ );
2864
+ return true;
2865
+ }
2866
+ if (!listConversion) {
2867
+ if (parsed.outPath) {
2868
+ const error = new Error(
2869
+ `${parsed.toolId} did not expose row-shaped output to write as CSV. Re-run with --json to inspect the raw tool response.`
2870
+ );
2871
+ if (_chunkF35VOIQLjs.argsWantJson.call(void 0, args)) {
2872
+ _chunkF35VOIQLjs.printJsonError.call(void 0, error);
2873
+ } else {
2874
+ console.error(error.message);
2875
+ }
2876
+ return false;
2877
+ }
2878
+ if (parsed.outputFormat === "csv" || parsed.outputFormat === "csv_file") {
2879
+ const jsonPath = _chunkNXDRDJ4Kjs.writeJsonOutputFile.call(void 0,
2880
+ rawResponse,
2881
+ `payload_${parsed.toolId}`
2882
+ );
2883
+ _chunkF35VOIQLjs.printCommandEnvelope.call(void 0,
2884
+ {
2885
+ ...baseEnvelope,
2886
+ local: {
2887
+ payload_file: jsonPath
2888
+ }
2889
+ },
2890
+ { json: parsed.outputFormat === "csv_file" || _chunkF35VOIQLjs.shouldEmitJson.call(void 0, ) }
2891
+ );
2892
+ return true;
2893
+ }
2894
+ _chunkF35VOIQLjs.printCommandEnvelope.call(void 0, baseEnvelope, { json: false });
2895
+ return true;
2896
+ }
2897
+ const rowOutput = _chunkNXDRDJ4Kjs.projectRowOutput.call(void 0, listConversion);
2898
+ const csv = _chunkNXDRDJ4Kjs.writeCsvOutputFile.call(void 0,
2899
+ listConversion.rows,
2900
+ `${parsed.toolId}_output`,
2901
+ parsed.outPath ? { outPath: parsed.outPath } : void 0
2902
+ );
2903
+ const seededScript = seedToolListScript({
2904
+ toolId: parsed.toolId,
2905
+ payload: parsed.params,
2906
+ rows: listConversion.rows
2907
+ });
2908
+ const materializedEnvelope = buildToolExecuteRowArtifactEnvelope({
2909
+ baseEnvelope,
2910
+ csv,
2911
+ rowOutput,
2912
+ summary,
2913
+ seededScript
2914
+ });
2915
+ if (parsed.outputFormat === "csv_file") {
2916
+ _chunkF35VOIQLjs.printCommandEnvelope.call(void 0, materializedEnvelope, { json: true });
2917
+ return true;
2918
+ }
2919
+ if (parsed.outPath) {
2920
+ _chunkF35VOIQLjs.printCommandEnvelope.call(void 0, materializedEnvelope, {
2921
+ json: _chunkF35VOIQLjs.argsWantJson.call(void 0, args) || _chunkF35VOIQLjs.shouldEmitJson.call(void 0, ),
2922
+ text: `Wrote ${csv.rowCount} row(s) to ${csv.path}
2923
+ `
2924
+ });
2925
+ return true;
2926
+ }
2927
+ if (parsed.noPreview) {
2928
+ _chunkF35VOIQLjs.printCommandEnvelope.call(void 0,
2929
+ {
2930
+ ...materializedEnvelope,
2931
+ local: {
2932
+ ..._nullishCoalesce(materializedEnvelope.local, () => ( {})),
2933
+ output_path: csv.path
2934
+ }
2935
+ },
2936
+ { json: _chunkF35VOIQLjs.shouldEmitJson.call(void 0, ), text: `${csv.path}
2937
+ ` }
2938
+ );
2939
+ return true;
2940
+ }
2941
+ _chunkF35VOIQLjs.printCommandEnvelope.call(void 0, materializedEnvelope, { json: false });
2942
+ return true;
2943
+ })();
2944
+ if (delivered) await recovery.acknowledgeDelivery();
2945
+ return delivered ? executeExitCode : 1;
2946
+ }
2947
+
2948
+
2949
+
2950
+
2951
+
2952
+
2953
+
2954
+
2955
+ exports.buildToolExecuteBaseEnvelope = buildToolExecuteBaseEnvelope; exports.extractToolExecutionWarningMessages = extractToolExecutionWarningMessages; exports.isMonitorTypeTool = isMonitorTypeTool; exports.printCompactToolContract = printCompactToolContract; exports.printMonitorTypeContract = printMonitorTypeContract; exports.registerToolsCommands = registerToolsCommands; exports.toolContractJsonForDescribe = toolContractJsonForDescribe;