deepline 0.3.395 → 0.3.396

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 (107) hide show
  1. package/dist/bundling-sources/sdk/src/plays/play-description.ts +1 -1
  2. package/dist/bundling-sources/sdk/src/release.ts +1 -1
  3. package/dist/bundling-sources/shared_libs/observability/scheduled-jobs.json +1 -1
  4. package/dist/cli/{auth-NMQXZRS7.mjs → auth-3LTD62VL.mjs} +4 -4
  5. package/dist/cli/auth-562JPKOM.js +39 -0
  6. package/dist/cli/{billing-5MVXZRS6.mjs → billing-DP7ZAJBO.mjs} +5 -5
  7. package/dist/cli/{billing-Z4JTGUU3.js → billing-PA5OXEM5.js} +76 -76
  8. package/dist/cli/{chunk-BLYL3KOC.mjs → chunk-23GAA3YO.mjs} +1 -1
  9. package/dist/cli/{chunk-LZLBR2SF.js → chunk-2VOLOWYZ.js} +1087 -1056
  10. package/dist/cli/{chunk-EFLQHJZ6.mjs → chunk-3T4MCB5R.mjs} +1026 -995
  11. package/dist/cli/{chunk-VB6KECLU.mjs → chunk-5WNJF2T3.mjs} +102 -36
  12. package/dist/cli/{chunk-UKU6JM3S.js → chunk-772W2SAU.js} +8 -8
  13. package/dist/cli/{chunk-K5T3EN6D.js → chunk-7Z66NHUC.js} +26 -26
  14. package/dist/cli/{chunk-WCCKMLHL.mjs → chunk-AUYXWELC.mjs} +2 -2
  15. package/dist/cli/{chunk-PZ5BZ76S.js → chunk-AVHLATII.js} +50 -50
  16. package/dist/cli/{chunk-MYIBHORT.js → chunk-DC6LTULT.js} +2 -2
  17. package/dist/cli/{chunk-5VCZ3WRH.mjs → chunk-EIMG75BT.mjs} +1 -0
  18. package/dist/cli/{chunk-TO2MWPGR.js → chunk-GNN4MY5X.js} +1 -1
  19. package/dist/cli/{chunk-OCSG6X67.mjs → chunk-I4T4XAA2.mjs} +4 -4
  20. package/dist/cli/{chunk-ZWH2TFA7.mjs → chunk-JCN4DHF7.mjs} +2 -2
  21. package/dist/cli/{chunk-R4XZO6Z5.js → chunk-KAEZNPUM.js} +23 -8
  22. package/dist/cli/{chunk-DRM3CMHL.js → chunk-KXMNM4AQ.js} +2 -1
  23. package/dist/cli/{chunk-3TRY7KAC.mjs → chunk-LOGGNW4H.mjs} +2 -2
  24. package/dist/cli/{chunk-RDXFGPJU.js → chunk-LWERJUKN.js} +218 -218
  25. package/dist/cli/{chunk-UCXK2DS4.js → chunk-ME6XRFLY.js} +15 -15
  26. package/dist/cli/{chunk-G4IWGRMK.mjs → chunk-MR6XCBQJ.mjs} +2 -2
  27. package/dist/cli/{chunk-BON3DRC6.mjs → chunk-NHB5YUCS.mjs} +1 -1
  28. package/dist/cli/{chunk-ZMVJSS6N.js → chunk-NSOTASOP.js} +101 -35
  29. package/dist/cli/{chunk-7XAM7KDW.mjs → chunk-QHGPA362.mjs} +18 -3
  30. package/dist/cli/{chunk-VYLJJQ7Y.js → chunk-RMTASUAK.js} +65 -65
  31. package/dist/cli/{chunk-HRWUQJ4K.js → chunk-RTO5QZWT.js} +6 -6
  32. package/dist/cli/{chunk-7MVWUXOD.mjs → chunk-TLQ3FZOC.mjs} +3 -3
  33. package/dist/cli/{chunk-56IFFVIB.js → chunk-V7UP2F4U.js} +4 -4
  34. package/dist/cli/{chunk-6D7A2FSL.mjs → chunk-VE3U3SQC.mjs} +1 -1
  35. package/dist/cli/{chunk-36ML3YKA.js → chunk-WQJJNIMQ.js} +13 -13
  36. package/dist/cli/{chunk-47M6HPGP.mjs → chunk-XKZXO7D3.mjs} +1 -1
  37. package/dist/cli/{csv-SVOD5UBH.mjs → csv-RLRR74RQ.mjs} +3 -3
  38. package/dist/cli/{csv-HTS5ZYQ4.js → csv-TF576S77.js} +12 -12
  39. package/dist/cli/{db-7AP4P52N.js → db-FDBJUTFO.js} +30 -30
  40. package/dist/cli/{db-7QLNI3Q4.mjs → db-XORGNBIC.mjs} +5 -5
  41. package/dist/cli/{describe-DBRY5BNK.mjs → describe-6O2ENKTP.mjs} +86 -68
  42. package/dist/cli/{describe-YKOE54ZO.js → describe-EFWNECHI.js} +100 -82
  43. package/dist/cli/{executions-GRQXTB2P.js → executions-SFYAXPF4.js} +7 -7
  44. package/dist/cli/{executions-QNZTPNG4.mjs → executions-YPP7WR77.mjs} +5 -5
  45. package/dist/cli/{feedback-ZOLA2KY7.js → feedback-5UZFYMGB.js} +7 -7
  46. package/dist/cli/{feedback-JMCSR624.mjs → feedback-RBGA5ARU.mjs} +3 -3
  47. package/dist/cli/git-5LDY5ZID.js +23 -0
  48. package/dist/cli/{git-LJGL2IHS.mjs → git-IRSAJEK2.mjs} +4 -4
  49. package/dist/cli/index.js +94 -94
  50. package/dist/cli/index.mjs +38 -38
  51. package/dist/cli/{legacy-noops-YSCIR2SD.js → legacy-noops-CVAOQY2F.js} +7 -7
  52. package/dist/cli/{legacy-noops-F23PKVBN.mjs → legacy-noops-NA7N6ZOU.mjs} +4 -4
  53. package/dist/cli/{monitors-WMZ6HJZX.js → monitors-4OMRXCXP.js} +86 -86
  54. package/dist/cli/{monitors-S4LOEL7W.mjs → monitors-ILZ2XHYG.mjs} +5 -5
  55. package/dist/cli/{org-U3WA2NQM.mjs → org-QDDXAE3J.mjs} +5 -5
  56. package/dist/cli/{org-PFHM5ZLY.js → org-YGNJDD2X.js} +65 -65
  57. package/dist/cli/{chunk-4KLCLLTO.js → play-L535H26U.js} +266 -323
  58. package/dist/cli/{chunk-XMAPE2KH.mjs → play-VT6OHB2D.mjs} +72 -129
  59. package/dist/cli/{providers-XYMHLKCA.js → providers-GPZ6PQAL.js} +8 -8
  60. package/dist/cli/{providers-QBBRFBOH.mjs → providers-KG4W5MPK.mjs} +5 -5
  61. package/dist/cli/{quickstart-5JTDGISY.mjs → quickstart-2JDGTXIG.mjs} +3 -3
  62. package/dist/cli/{quickstart-IYGD6ZY3.js → quickstart-UI27S5LO.js} +5 -5
  63. package/dist/cli/search-MGWROZ33.js +28 -0
  64. package/dist/cli/{search-X6W6GRHS.mjs → search-PW3RAUX7.mjs} +6 -6
  65. package/dist/cli/{secrets-N55B67H6.mjs → secrets-HNOMK5A2.mjs} +5 -5
  66. package/dist/cli/{secrets-UHG6OQFD.js → secrets-WFAXOUZE.js} +14 -14
  67. package/dist/cli/{sessions-57L5MGHN.js → sessions-366KROUA.js} +5 -5
  68. package/dist/cli/{sessions-JTRSTDSS.mjs → sessions-XLX3E5UO.mjs} +4 -4
  69. package/dist/cli/{settings-ATX4U5AS.js → settings-GADAG2UK.js} +75 -75
  70. package/dist/cli/{settings-Q24HRAQI.mjs → settings-YNZ4YKCH.mjs} +8 -8
  71. package/dist/cli/{setup-77ZWLVHT.mjs → setup-PSEHIUXO.mjs} +6 -6
  72. package/dist/cli/{setup-EJCNOUCE.js → setup-R5YO7GT6.js} +41 -41
  73. package/dist/cli/skills-JF2LPEGM.js +28 -0
  74. package/dist/cli/{skills-XIS5AWQI.mjs → skills-LTQBP6CZ.mjs} +4 -4
  75. package/dist/cli/tools-CP2PEFRN.js +34 -0
  76. package/dist/cli/{tools-WCKLYEGQ.mjs → tools-UAXDWU63.mjs} +11 -19
  77. package/dist/cli/update-HZHZOU6C.js +28 -0
  78. package/dist/cli/{update-UT5WANMV.mjs → update-SMNIBIMS.mjs} +6 -6
  79. package/dist/cli/{workflow-226QYUN2.js → workflow-AOQVZHMD.js} +16 -16
  80. package/dist/cli/{workflow-ZMX3L4ML.mjs → workflow-IKGMBGF6.mjs} +6 -6
  81. package/dist/{client-CivP-PAI.d.ts → client-Bgis7F6-.d.ts} +2 -1
  82. package/dist/{client-hdFtwhTm.d.mts → client-DiGl8ska.d.mts} +2 -1
  83. package/dist/index.d.mts +2 -2
  84. package/dist/index.d.ts +2 -2
  85. package/dist/index.js +11 -11
  86. package/dist/index.mjs +9 -9
  87. package/dist/install-integrity.json +78 -80
  88. package/dist/plays/play-description.d.mts +1 -1
  89. package/dist/plays/play-description.d.ts +1 -1
  90. package/dist/plays/play-description.js +4 -2
  91. package/dist/plays/play-description.mjs +3 -1
  92. package/dist/plays/run-request.d.mts +1 -1
  93. package/dist/plays/run-request.d.ts +1 -1
  94. package/dist/release.d.mts +1 -1
  95. package/dist/release.d.ts +1 -1
  96. package/dist/release.js +2 -2
  97. package/dist/release.mjs +1 -1
  98. package/package.json +1 -1
  99. package/dist/cli/auth-UYCOBAL5.js +0 -39
  100. package/dist/cli/git-EJQLRK27.js +0 -23
  101. package/dist/cli/play-AGSECQFN.mjs +0 -159
  102. package/dist/cli/play-BR2LWGXK.js +0 -159
  103. package/dist/cli/search-ZVSYH5GY.js +0 -28
  104. package/dist/cli/skills-SPXUBLII.js +0 -28
  105. package/dist/cli/tools-DBHUUZJX.js +0 -42
  106. package/dist/cli/update-VSNFXRHJ.js +0 -28
  107. package/dist/cli/{chunk-KZZC33PY.mjs → chunk-H5KLUGY7.mjs} +214 -214
@@ -4,7 +4,7 @@ import {
4
4
  recordApiResponse,
5
5
  schemaField,
6
6
  schemaFields
7
- } from "./chunk-VB6KECLU.mjs";
7
+ } from "./chunk-5WNJF2T3.mjs";
8
8
  import {
9
9
  shellQuote
10
10
  } from "./chunk-OVDNJAJN.mjs";
@@ -13,7 +13,7 @@ import {
13
13
  observedMaxText,
14
14
  recentSearchRef,
15
15
  registerDeprecatedSearchCommand
16
- } from "./chunk-7XAM7KDW.mjs";
16
+ } from "./chunk-QHGPA362.mjs";
17
17
  import {
18
18
  DEEPLINE_EXTRACTOR_TARGET_DEFINITIONS,
19
19
  EMAIL_STATUS_JSON_SCHEMA,
@@ -24,14 +24,14 @@ import {
24
24
  tryConvertToList,
25
25
  writeCsvOutputFile,
26
26
  writeJsonOutputFile
27
- } from "./chunk-KZZC33PY.mjs";
27
+ } from "./chunk-H5KLUGY7.mjs";
28
28
  import {
29
29
  playToolListGetterMode
30
30
  } from "./chunk-3HU47EGZ.mjs";
31
31
  import {
32
32
  DeeplineClient,
33
33
  validateExecutionIdempotencyKey
34
- } from "./chunk-G4IWGRMK.mjs";
34
+ } from "./chunk-MR6XCBQJ.mjs";
35
35
  import {
36
36
  stableStringify
37
37
  } from "./chunk-UBKA33KY.mjs";
@@ -48,11 +48,11 @@ import {
48
48
  printJsonError,
49
49
  renderCommandEnvelopeText,
50
50
  shouldEmitJson
51
- } from "./chunk-47M6HPGP.mjs";
51
+ } from "./chunk-XKZXO7D3.mjs";
52
52
  import {
53
53
  resolveConfig,
54
54
  sdkCliStateDirPath
55
- } from "./chunk-6D7A2FSL.mjs";
55
+ } from "./chunk-VE3U3SQC.mjs";
56
56
  import {
57
57
  DeeplineError
58
58
  } from "./chunk-NXGCO4JB.mjs";
@@ -195,36 +195,6 @@ async function completePendingToolExecution(path, idempotencyKey) {
195
195
  }
196
196
  }
197
197
 
198
- // ../plays/tool-category-descriptions.ts
199
- var TOOL_CATEGORY_DESCRIPTIONS = {
200
- company_search: "Find companies matching firmographic, ad, or web criteria.",
201
- people_search: "Find people matching role, company, or persona criteria.",
202
- people_enrich: "Enrich a known person with contact, social, and profile data.",
203
- company_enrich: "Enrich a known company with firmographic and account data.",
204
- email_finder: "Find work or personal email addresses for a person.",
205
- email_verify: "Validate email deliverability and catch-all status.",
206
- phone_finder: "Find mobile or direct phone numbers for a person.",
207
- phone_verify: "Validate phone-number reachability and line type.",
208
- research: "Research accounts, people, news, and signals for context and scoring.",
209
- autocomplete: "Resolve names and entities to canonical catalog records.",
210
- automation: "Kick off provider-side jobs, exports, and asynchronous workflows.",
211
- outbound_tools: "Run outbound sequencing, deliverability, and campaign operations.",
212
- admin: "Provider-side status, metadata, and account operations behind other tools.",
213
- smb: "Look up small-business listings, local records, and public filings.",
214
- identity_resolution: "Match a partial identity to a single resolved person or company.",
215
- reverse_lookup: "Resolve an email, phone, or profile back to a person.",
216
- enrichment: "General-purpose record enrichment across people and companies.",
217
- batch: "Run an enrichment or search operation over many rows at once.",
218
- premium: "Higher-cost tools with premium provider coverage.",
219
- free: "Free tools that do not spend Deepline credits."
220
- };
221
- var WELL_KNOWN_TOOL_CATEGORIES = Object.freeze(
222
- Object.keys(TOOL_CATEGORY_DESCRIPTIONS)
223
- );
224
- function describeToolCategory(category) {
225
- return TOOL_CATEGORY_DESCRIPTIONS[category] ?? null;
226
- }
227
-
228
198
  // ../plays/field-catalog.ts
229
199
  var value = (description) => ({ type: "string", description });
230
200
  var SOURCE = {
@@ -398,116 +368,803 @@ function fieldOfName(name, declared) {
398
368
  return meanings.some((meaning) => fieldSatisfies(declared, meaning)) ? declared : void 0;
399
369
  }
400
370
 
401
- // src/cli/commands/model-description.ts
402
- function formatModelDescription(description) {
403
- const lines = [];
404
- lines.push(description.model);
405
- lines.push(`Provider: ${description.provider}`);
406
- const name = stringField(description.modelMetadata, "name");
407
- if (name) lines.push(`Name: ${name}`);
408
- const contextWindow = numberField(
409
- description.modelMetadata,
410
- "context_window"
411
- );
412
- if (contextWindow !== null) lines.push(`Context: ${contextWindow}`);
413
- const tags = arrayField(description.modelMetadata, "tags").filter(
414
- (value2) => typeof value2 === "string"
415
- );
416
- if (tags.length) lines.push(`Tags: ${tags.join(", ")}`);
417
- lines.push("");
418
- lines.push("Provider options:");
419
- appendNamespace(lines, description.providerOptions.gateway);
420
- if (description.providerOptions.selectedProvider) {
421
- appendNamespace(lines, description.providerOptions.selectedProvider);
422
- }
423
- lines.push("");
424
- lines.push("Example input:");
425
- lines.push(JSON.stringify(description.exampleInput, null, 2));
426
- if (description.caveats.length) {
427
- lines.push("");
428
- lines.push("Caveats:");
429
- for (const caveat of description.caveats) {
430
- lines.push(`- ${caveat}`);
431
- }
432
- }
433
- return `${lines.join("\n")}
434
- `;
371
+ // src/cli/described-tool.ts
372
+ function isPlayLikeTool(tool) {
373
+ const record = tool;
374
+ if (record.isPlay === true || record.is_play === true) return true;
375
+ const playExpansion = recordField(record, "playExpansion", "play_expansion");
376
+ if (Object.keys(playExpansion).length > 0) return true;
377
+ const toolId = typeof record.toolId === "string" ? record.toolId : "";
378
+ return toolId.endsWith("_waterfall");
435
379
  }
436
- function appendNamespace(lines, namespace) {
437
- lines.push(`- ${namespace.provider} (${namespace.sourceSymbol})`);
438
- for (const field of namespace.fields) {
439
- const values = field.enumValues?.length ? ` (${field.enumValues.map((value2) => JSON.stringify(value2)).join(" | ")})` : "";
440
- lines.push(
441
- ` - ${field.name}: ${field.type}${values} - ${field.description}`
442
- );
380
+ function isMonitorTypeTool(tool) {
381
+ return stringField(tool, "kind") === "monitor_type";
382
+ }
383
+ function playReferenceForTool(tool) {
384
+ const record = tool;
385
+ const declared = stringField(record, "playReference", "play_reference");
386
+ if (declared.startsWith("prebuilt/")) {
387
+ return declared;
443
388
  }
389
+ return null;
444
390
  }
445
- function stringField(value2, key) {
446
- if (!value2 || typeof value2 !== "object" || Array.isArray(value2)) return null;
447
- const candidate = value2[key];
448
- return typeof candidate === "string" && candidate.trim() ? candidate.trim() : null;
391
+ function playSearchCommandForToolId(toolId) {
392
+ return `deepline search --type prebuilts ${JSON.stringify(toolId.replace(/_/g, " "))}`;
449
393
  }
450
- function numberField(value2, key) {
451
- if (!value2 || typeof value2 !== "object" || Array.isArray(value2)) return null;
452
- const candidate = value2[key];
453
- return typeof candidate === "number" ? candidate : null;
394
+ function playRunCommandForTool(tool, toolId, input) {
395
+ const playReference = playReferenceForTool(tool);
396
+ if (!playReference) return playSearchCommandForToolId(toolId);
397
+ const inputArg = input === void 0 ? "'{...}'" : `'${JSON.stringify(input)}'`;
398
+ return `deepline plays run ${playReference} --input ${inputArg}`;
454
399
  }
455
- function arrayField(value2, key) {
456
- if (!value2 || typeof value2 !== "object" || Array.isArray(value2)) return [];
457
- const candidate = value2[key];
458
- return Array.isArray(candidate) ? candidate : [];
400
+ function toolContractJsonForDescribe(tool, requestedToolId, authoringContractEdition, seedStarterScript) {
401
+ const toolId = String(tool.toolId || requestedToolId);
402
+ const inputFields = toolInputFieldsForDisplay(
403
+ recordField(tool, "inputSchema", "input_schema")
404
+ );
405
+ const inputSchema = publicToolInputSchemaForDescribe(
406
+ recordField(tool, "inputSchema", "input_schema")
407
+ );
408
+ const outputSchemaRecord = recordField(tool, "outputSchema", "output_schema");
409
+ const outputFields = toolOutputFieldsForDisplay(outputSchemaRecord);
410
+ const usageGuidance = recordField(tool, "usageGuidance", "usage_guidance");
411
+ const guidance = recordField(tool, "guidance");
412
+ const toolExecutionResult = recordField(
413
+ usageGuidance,
414
+ "toolExecutionResult",
415
+ "tool_execution_result"
416
+ );
417
+ const extractedLists = extractionContractEntries(
418
+ arrayField(toolExecutionResult, "extractedLists", "extracted_lists")
419
+ ).map((entry) => ({
420
+ ...entry,
421
+ returnType: playToolListGetterMode(authoringContractEdition) === "array" ? "Array" : "PlayDataset",
422
+ rowsExpression: playToolListGetterMode(authoringContractEdition) === "array" ? entry.expression : `await ${entry.expression}.materialize()`
423
+ }));
424
+ const extractedValues = extractionContractEntries(
425
+ arrayField(toolExecutionResult, "extractedValues", "extracted_values")
426
+ );
427
+ const pricing = Capability.fromCatalogEntry(tool).describe().customerCost();
428
+ const executionMetadataRecord = recordField(
429
+ tool,
430
+ "executionMetadata",
431
+ "execution_metadata"
432
+ );
433
+ const executionMetadata = Object.keys(executionMetadataRecord).length > 0 ? executionMetadataRecord : null;
434
+ const batchCapabilityRecord = recordField(
435
+ tool,
436
+ "batchCapability",
437
+ "batch_capability"
438
+ );
439
+ const batchCapability = Object.keys(batchCapabilityRecord).length > 0 ? batchCapabilityRecord : null;
440
+ const deprecation = recordField(tool, "deprecation");
441
+ const replacementToolId = stringField(
442
+ deprecation,
443
+ "replacementToolId",
444
+ "replacement_tool_id"
445
+ );
446
+ const deprecationMessage = stringField(deprecation, "message");
447
+ const deprecationExecution = stringField(deprecation, "execution");
448
+ const deprecated = tool.deprecated === true || stringField(tool, "credentialStatus", "credential_status") === "deprecated";
449
+ const starterScript = seedStarterScript && !deprecated && !isPlayLikeTool(tool) && extractedLists.length > 0 ? starterScriptJson(
450
+ seedStarterScript({
451
+ toolId,
452
+ payload: samplePayloadForInputFields(inputFields),
453
+ rows: []
454
+ })
455
+ ) : null;
456
+ const executeCommand = deprecated && replacementToolId ? `deepline tools execute ${replacementToolId} --input '{...}'` : isPlayLikeTool(tool) ? playRunCommandForTool(tool, toolId) : `deepline tools execute ${toolId} --input '{...}'`;
457
+ return {
458
+ schemaVersion: 1,
459
+ toolId,
460
+ provider: tool.provider,
461
+ displayName: tool.displayName,
462
+ cost: pricing,
463
+ description: tool.description,
464
+ ...Object.keys(guidance).length > 0 ? { guidance } : {},
465
+ categories: tool.categories,
466
+ ...Array.isArray(tool.requestWarnings) ? { requestWarnings: tool.requestWarnings } : {},
467
+ ...deprecated ? {
468
+ deprecated: true,
469
+ callable: tool.callable !== false,
470
+ deprecation: {
471
+ replacementToolId,
472
+ message: deprecationMessage,
473
+ ...deprecationExecution ? { execution: deprecationExecution } : {}
474
+ }
475
+ } : {},
476
+ inputFields: inputFields.map(inputFieldJsonForDescribe),
477
+ inputSchema,
478
+ ...isRecord(tool.responseSchema) ? { responseSchema: tool.responseSchema } : {},
479
+ ...Array.isArray(tool.examples) ? { examples: tool.examples } : {},
480
+ responseAccess: "result.toolResponse.rawV2",
481
+ ...Object.keys(outputSchemaRecord).length > 0 ? {
482
+ outputSchema: publicToolInputSchemaForDescribe(outputSchemaRecord),
483
+ outputFields: outputFields.map(inputFieldJsonForDescribe)
484
+ } : {},
485
+ ...executionMetadata ? { executionMetadata } : {},
486
+ ...batchCapability ? { batchCapability } : {},
487
+ getters: {
488
+ extractedLists,
489
+ extractedValues
490
+ },
491
+ executeCommand,
492
+ ...starterScript ? { starterScript } : {}
493
+ };
459
494
  }
460
-
461
- // src/cli/tool-connection-status.ts
462
- function toolConnectionStatusMessage(input) {
463
- if (input.credentialStatus === "requires_connection") {
464
- return "requires your credentials \u2014 not connected (connect to use)";
465
- }
466
- if (input.connected === false && input.credentialStatus === "managed") {
467
- return "temporarily unavailable";
495
+ function extractionContractEntries(entries) {
496
+ return entries.flatMap((entry) => {
497
+ if (!isRecord(entry)) return [];
498
+ const name = stringField(entry, "name");
499
+ const expression = stringField(entry, "expression");
500
+ return name && expression ? [{ name, expression }] : [];
501
+ });
502
+ }
503
+ function schemaNodeAt(schema, path) {
504
+ let node = schema;
505
+ for (const part of path.split(".").filter(Boolean)) {
506
+ const [key, ...indexes] = part.split("[");
507
+ node = recordField(isRecord(node) ? node : {}, "properties")[key];
508
+ for (const _index of indexes)
509
+ node = isRecord(node) ? node.items : void 0;
468
510
  }
469
- return null;
511
+ return node;
470
512
  }
471
-
472
- // src/cli/commands/tools.ts
473
- var TOOL_COMMAND_TEMPLATES = {
474
- describe: "deepline describe <toolId>",
475
- execute: "deepline tools execute <toolId> --input '{...}'"
513
+ var NAMED_VALUE_SHAPES = {
514
+ email_status: { shape: "EmailStatus", schema: EMAIL_STATUS_JSON_SCHEMA },
515
+ job_change: { shape: "JobChange", schema: JOB_CHANGE_JSON_SCHEMA }
476
516
  };
477
- function toListedTool(tool) {
478
- if (isPlayLikeTool(tool)) {
517
+ function extractorValueType(name) {
518
+ if (!isDeeplineExtractorTarget(name)) return void 0;
519
+ const definition = DEEPLINE_EXTRACTOR_TARGET_DEFINITIONS[name];
520
+ if (definition.enum) {
479
521
  return {
480
- ...tool,
481
- description: listedToolDescription(tool),
482
- id: tool.toolId,
483
- type: "play",
484
- executeCommand: playRunCommandForTool(tool, tool.toolId)
522
+ type: definition.enum.map((value2) => JSON.stringify(value2)).join(" | ")
485
523
  };
486
524
  }
487
- return {
488
- ...tool,
489
- description: listedToolDescription(tool),
490
- id: tool.toolId,
491
- type: "tool",
492
- executeCommand: `deepline tools execute ${tool.toolId}`
493
- };
525
+ const named = NAMED_VALUE_SHAPES[definition.valueKind];
526
+ if (!named) return { type: "string" };
527
+ const { type, fields } = schemaField(name, named.schema, true);
528
+ return { type, ...fields ? { fields } : {}, shape: named.shape };
494
529
  }
495
- function normalizeGrepText(value2) {
496
- if (value2 === null || value2 === void 0) return "";
497
- if (typeof value2 === "string") return value2.toLowerCase();
498
- if (typeof value2 === "number" || typeof value2 === "boolean") {
499
- return String(value2).toLowerCase();
500
- }
501
- if (Array.isArray(value2)) return value2.map(normalizeGrepText).join(" ");
502
- if (typeof value2 === "object") {
503
- return Object.values(value2).map(normalizeGrepText).join(" ");
504
- }
505
- return "";
530
+ function jsonSchemaOf(wrapper) {
531
+ return isRecord(wrapper.jsonSchema) ? wrapper.jsonSchema : wrapper;
506
532
  }
507
- function parseGrepTerms(query, mode) {
508
- const trimmed = query.trim().toLowerCase();
509
- if (!trimmed) return [];
510
- if (mode === "phrase") return [trimmed];
533
+ function publicToolSchemas(tool) {
534
+ const scrubbed = (...keys) => {
535
+ const schema = recordField(tool, ...keys);
536
+ if (Object.keys(schema).length === 0) return null;
537
+ const cleaned = publicToolInputSchemaForDescribe(schema);
538
+ return isRecord(cleaned.jsonSchema) ? cleaned.jsonSchema : cleaned;
539
+ };
540
+ const responseSchema = scrubbed("responseSchema", "response_schema");
541
+ return {
542
+ inputSchema: scrubbed(
543
+ "inputSchema",
544
+ "input_schema",
545
+ "payload_schema",
546
+ "payloadSchema"
547
+ ),
548
+ outputSchema: scrubbed("outputSchema", "output_schema"),
549
+ ...responseSchema ? { responseSchema } : {}
550
+ };
551
+ }
552
+ function describedTool(tool, requestedToolId) {
553
+ const id = stringField(tool, "toolId") || requestedToolId;
554
+ const displayName = stringField(tool, "displayName") || void 0;
555
+ const description = stringField(tool, "bestFor", "best_for") || stringField(tool, "description") || void 0;
556
+ if (isMonitorTypeTool(tool)) {
557
+ return {
558
+ kind: "monitor_type",
559
+ id,
560
+ displayName,
561
+ description,
562
+ cost: stringField(recordField(tool, "pricing"), "displayText") || void 0,
563
+ guidance: [],
564
+ inputs: schemaFields(
565
+ recordField(tool, "payload_schema", "payloadSchema")
566
+ ),
567
+ outputs: [],
568
+ runner: {
569
+ via: "monitor",
570
+ deploy: stringField(recordField(tool, "deploy"), "example") || `deepline monitors deploy '{"key":"...","tool":"${id}","payload":{...}}'`
571
+ }
572
+ };
573
+ }
574
+ const contract = toolContractJsonForDescribe(tool, requestedToolId);
575
+ const cost = recordField(contract, "cost");
576
+ const billing = stringField(cost, "billingSourceLabel");
577
+ const deprecation = recordField(contract, "deprecation");
578
+ const getters = recordField(contract, "getters");
579
+ const outputSchema = jsonSchemaOf(recordField(contract, "outputSchema"));
580
+ const toolResult = recordField(tool, "toolResult", "tool_result");
581
+ const getterDetails = (kind) => new Map(
582
+ arrayField(toolResult, kind).filter(isRecord).map((item) => [
583
+ stringField(item, "name"),
584
+ recordField(item, "details")
585
+ ])
586
+ );
587
+ const declared = recordField(tool, "extractors");
588
+ const getterOutputs = (kind, roots) => {
589
+ const details = getterDetails(kind);
590
+ return arrayField(getters, kind).filter(isRecord).map((entry) => {
591
+ const name = stringField(entry, "name");
592
+ const rawPaths = arrayField(
593
+ details.get(name) ?? {},
594
+ "rawToolOutputPaths"
595
+ ).map(String);
596
+ const paths = rawPaths.map(
597
+ (path) => path.replace(/^toolResponse\.raw\./, "")
598
+ );
599
+ const node = roots.flatMap((root) => paths.map((path) => schemaNodeAt(root, path))).find(isRecord);
600
+ const { fields, ...typed } = schemaField(name, node, true);
601
+ const valueType = stringField(details.get(name) ?? {}, "valueType");
602
+ const deepline = kind === "extractedValues" ? extractorValueType(name) : void 0;
603
+ const known = typed.type !== "unknown" ? void 0 : kind === "extractedLists" ? { type: "object[]" } : deepline;
604
+ const means = kind === "extractedValues" ? fieldOfName(
605
+ name,
606
+ stringField(declared[name] ?? {}, "means") || void 0
607
+ ) : void 0;
608
+ const field = {
609
+ ...typed,
610
+ ...means ? { means } : {},
611
+ // A normalized value has a named type instead of the response's
612
+ // shape; a normalized object is spelled out once under Types.
613
+ ...deepline?.shape ? deepline : valueType ? { type: valueType } : known ? known : fields ? { fields } : {},
614
+ // A list's row columns that matter are value getters of their own.
615
+ ...kind === "extractedLists" && fields ? { summarized: true } : {},
616
+ read: playResultExpression(entry),
617
+ ...rawPaths.length ? { paths: rawPaths } : {}
618
+ };
619
+ return { field, node };
620
+ });
621
+ };
622
+ const declaredLists = getterOutputs("extractedLists", [outputSchema]);
623
+ const lists = declaredLists.some(({ node }) => node) ? declaredLists.filter(({ node }) => node) : declaredLists;
624
+ const values = getterOutputs("extractedValues", [
625
+ outputSchema,
626
+ ...lists.map(({ node }) => node?.items)
627
+ ]).map((value2) => {
628
+ if (!lists.length || !value2.field.paths) return value2;
629
+ const within = value2.field.paths.map(
630
+ (path) => path.replace(/^toolResponse\.raw\./, "")
631
+ );
632
+ const list = lists.find(
633
+ ({ node }) => within.some((path) => isRecord(schemaNodeAt(node?.items, path)))
634
+ ) ?? lists[0];
635
+ return {
636
+ ...value2,
637
+ field: { ...value2.field, in: list.field.name, paths: within }
638
+ };
639
+ });
640
+ const playReference = isPlayLikeTool(tool) ? playReferenceForTool(tool) : null;
641
+ return {
642
+ kind: "tool",
643
+ id: String(contract.toolId),
644
+ displayName,
645
+ description,
646
+ cost: [
647
+ stringField(cost, "displayText"),
648
+ // "Free (free)" says the same thing twice.
649
+ billing.toLowerCase() === stringField(cost, "displayText").toLowerCase() ? "" : billing && `(${billing})`,
650
+ observedMaxText(cost) && `\u2014 ${observedMaxText(cost)}`
651
+ ].filter(Boolean).join(" ") || void 0,
652
+ guidance: [
653
+ ...contract.deprecated === true ? [`Deprecated. ${stringField(deprecation, "message")}`.trim()] : [],
654
+ ...Object.values(recordField(contract, "guidance")).filter(
655
+ (line) => typeof line === "string" && /[a-z0-9]/i.test(line)
656
+ )
657
+ ],
658
+ rateLimit: rateLimitSummary(
659
+ recordField(contract, "executionMetadata").configuredRateLimits
660
+ ),
661
+ inputs: schemaFields(jsonSchemaOf(recordField(contract, "inputSchema"))),
662
+ outputs: [...lists, ...values].map(({ field }) => field),
663
+ rawResponse: schemaFields(outputSchema),
664
+ runner: playReference ? { via: "play", reference: playReference } : { via: "tool", toolId: String(contract.toolId) }
665
+ };
666
+ }
667
+ function sampleValueForField(field) {
668
+ const name = stringField(field, "name").toLowerCase();
669
+ const type = stringField(field, "type").toLowerCase();
670
+ if (Object.prototype.hasOwnProperty.call(field, "default"))
671
+ return field.default;
672
+ if (name.includes("email")) return "ada@example.com";
673
+ if (name.includes("domain") || name.includes("website")) return "example.com";
674
+ if (name.includes("first")) return "Ada";
675
+ if (name.includes("last")) return "Lovelace";
676
+ if (name.includes("name")) return "Ada Lovelace";
677
+ if (type === "integer" || type === "number") return 1;
678
+ if (type === "boolean") return true;
679
+ if (type === "array") return [];
680
+ if (type === "object") return {};
681
+ return "...";
682
+ }
683
+ function samplePayloadForInputFields(fields) {
684
+ return Object.fromEntries(
685
+ fields.slice(0, 4).flatMap((field) => {
686
+ if (!isRecord(field)) return [];
687
+ const name = stringField(field, "name");
688
+ if (!name) return [];
689
+ return [[name, sampleValueForField(field)]];
690
+ })
691
+ );
692
+ }
693
+ function playResultExpression(entry) {
694
+ return stringField(entry, "expression").replace(
695
+ /^toolExecutionResult\./,
696
+ "result."
697
+ );
698
+ }
699
+ function toolMetadataJsonForDescribe(tool, requestedToolId, seedStarterScript) {
700
+ const toolId = String(tool.toolId || requestedToolId);
701
+ const inputFields = toolInputFieldsForDisplay(
702
+ recordField(tool, "inputSchema", "input_schema")
703
+ );
704
+ const usageGuidance = usageGuidanceWithAccessDefaults(
705
+ recordField(tool, "usageGuidance", "usage_guidance")
706
+ );
707
+ const toolExecutionResult = recordField(
708
+ usageGuidance,
709
+ "toolExecutionResult",
710
+ "tool_execution_result"
711
+ );
712
+ const extractedLists = extractionContractEntries(
713
+ arrayField(toolExecutionResult, "extractedLists", "extracted_lists")
714
+ );
715
+ const starterScript = seedStarterScript && !isPlayLikeTool(tool) && extractedLists.length > 0 ? starterScriptJson(
716
+ seedStarterScript({
717
+ toolId,
718
+ payload: samplePayloadForInputFields(inputFields),
719
+ rows: []
720
+ })
721
+ ) : null;
722
+ const observedOutputCommand = isPlayLikeTool(tool) ? playRunCommandForTool(tool, toolId) : `deepline tools execute ${toolId} --input '{...}'`;
723
+ const {
724
+ cost: _cost,
725
+ deeplineCreditsPerPricingUnit: _deeplineCreditsPerPricingUnit,
726
+ deeplineUsdPerPricingUnit: _deeplineUsdPerPricingUnit,
727
+ deeplineUsdPerCredit: _deeplineUsdPerCredit,
728
+ deeplinePricingSummary: _deeplinePricingSummary,
729
+ deeplinePricingDetails: _deeplinePricingDetails,
730
+ deepline_credits_per_pricing_unit: _snakeDeeplineCreditsPerPricingUnit,
731
+ deepline_usd_per_pricing_unit: _snakeDeeplineUsdPerPricingUnit,
732
+ deepline_usd_per_credit: _snakeDeeplineUsdPerCredit,
733
+ deepline_pricing_summary: _snakeDeeplinePricingSummary,
734
+ deepline_pricing_details: _snakeDeeplinePricingDetails,
735
+ // BYOK is shown only on request, via describe --feature byok.
736
+ byok: _byok,
737
+ ...publicTool
738
+ } = tool;
739
+ const outputSchemaRecord = recordField(tool, "outputSchema", "output_schema");
740
+ return {
741
+ cost: Capability.fromCatalogEntry(tool).describe().customerCost(),
742
+ ...publicTool,
743
+ toolId,
744
+ provider: tool.provider,
745
+ displayName: tool.displayName,
746
+ ...Object.keys(outputSchemaRecord).length > 0 ? {
747
+ outputSchema: publicToolInputSchemaForDescribe(outputSchemaRecord),
748
+ outputFields: toolOutputFieldsForDisplay(outputSchemaRecord).map(
749
+ inputFieldJsonForDescribe
750
+ )
751
+ } : {},
752
+ inputFields: inputFields.map(inputFieldJsonForDescribe),
753
+ usageGuidance,
754
+ runtimeOutputHelp: {
755
+ contract: "Schemas declare field shapes. Examples illustrate input payloads and full Deepline execution responses; they are not observed responses from this call.",
756
+ getterScope: "extractedValues/extractedLists .get() only works for declared Deepline getters listed in usageGuidance.toolExecutionResult.",
757
+ 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.",
758
+ invalidGetterHint: "If TypeScript says an extractedValues/extractedLists property does not exist, that field is not a declared Deepline getter.",
759
+ observeActualShape: observedOutputCommand,
760
+ observedOutput: observedOutputCommand,
761
+ forPlayGetterBugs: "Run a tiny play, inspect returned handles with `deepline runs get <run-id> --full`, then export row datasets with `deepline runs export`.",
762
+ executeOutputFields: "tools execute JSON may include output_preview for this direct probe only; play debugging uses run output and returned dataset handles."
763
+ },
764
+ ...starterScript ? { starterScript } : {}
765
+ };
766
+ }
767
+ function usageGuidanceWithAccessDefaults(usageGuidance) {
768
+ if (Object.keys(usageGuidance).length === 0) return usageGuidance;
769
+ const existingAccess = recordField(usageGuidance, "access");
770
+ return {
771
+ ...usageGuidance,
772
+ prefer: [
773
+ "Use only the declared extractedLists and extractedValues getters listed below.",
774
+ "Use toolExecutionResult.toolResponse.rawV2 for the complete tool response, preserving the nesting shown in the response example.",
775
+ "Schemas declare field shapes; examples illustrate input values and full Deepline execution responses."
776
+ ],
777
+ toolExecutionResult: {
778
+ ...recordField(
779
+ usageGuidance,
780
+ "toolExecutionResult",
781
+ "tool_execution_result"
782
+ ),
783
+ toolResponse: {
784
+ rawV2: "toolResponse.rawV2",
785
+ view: "toolResponse.view",
786
+ responseMeta: "toolResponse.responseMeta"
787
+ }
788
+ },
789
+ access: {
790
+ ...existingAccess,
791
+ extractedValues: {
792
+ expression: "toolExecutionResult.extractedValues.<name>.get()",
793
+ meaning: "Declared Deepline scalar or normalized object extractors only."
794
+ },
795
+ ...existingAccess,
796
+ extractedLists: {
797
+ ...recordField(existingAccess, "extractedLists"),
798
+ expression: "toolExecutionResult.extractedLists.<name>.get()",
799
+ meaning: playToolListGetterMode() === "array" ? "Returns an ordinary array from this response. Use array methods directly or pass it to ctx.dataset to persist row work. Lazy or incomplete lists throw; use readList for an explicit dataset read. It does not fetch provider pages." : "Returns a PlayDataset, not a JavaScript array. Pass the handle to ctx.dataset, use first(), async iteration, or await handle.materialize() for the complete current list within the memory cap. materialize(n) and peek(n) return a prefix; none fetch additional provider pages. A missing getter is not an empty list."
800
+ },
801
+ rawToolResponse: {
802
+ expression: "toolExecutionResult.toolResponse.rawV2",
803
+ meaning: "Complete tool response with its original nesting. Read tool-specific fields here; use declared getters for extracted values and lists."
804
+ },
805
+ canonicalToolResponse: {
806
+ expression: "toolExecutionResult.toolResponse.rawV2",
807
+ meaning: "Complete tool response with its original nesting and sibling fields."
808
+ },
809
+ 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."
810
+ }
811
+ };
812
+ }
813
+ function toolInputFieldsForDisplay(inputSchema) {
814
+ if (Array.isArray(inputSchema.fields)) {
815
+ const fields = inputSchema.fields.filter(isRecord);
816
+ if (!isRecord(inputSchema.jsonSchema)) return fields;
817
+ const jsonSchemaFields = new Map(
818
+ recursiveToolInputFieldsForDisplay({
819
+ jsonSchema: inputSchema.jsonSchema
820
+ }).flatMap(
821
+ (field) => typeof field.name === "string" ? [[field.name, field]] : []
822
+ )
823
+ );
824
+ return fields.map((field) => {
825
+ const jsonSchemaField = typeof field.name === "string" ? jsonSchemaFields.get(field.name) : void 0;
826
+ const minItems = typeof field.minItems === "number" ? field.minItems : jsonSchemaField?.minItems;
827
+ const maxItems = typeof field.maxItems === "number" ? field.maxItems : jsonSchemaField?.maxItems;
828
+ const items = isRecord(field.items) ? field.items : jsonSchemaField?.items;
829
+ return {
830
+ ...field,
831
+ ...isRecord(items) ? { items } : {},
832
+ ...typeof minItems === "number" ? { minItems } : {},
833
+ ...typeof maxItems === "number" ? { maxItems } : {}
834
+ };
835
+ });
836
+ }
837
+ const jsonSchema = isRecord(inputSchema.jsonSchema) ? inputSchema.jsonSchema : inputSchema;
838
+ const properties = isRecord(jsonSchema.properties) ? jsonSchema.properties : {};
839
+ const required = Array.isArray(jsonSchema.required) ? new Set(jsonSchema.required.map(String)) : /* @__PURE__ */ new Set();
840
+ return Object.entries(properties).map(([name, value2]) => {
841
+ const property = isRecord(value2) ? value2 : {};
842
+ return {
843
+ name,
844
+ type: typeof property.type === "string" ? property.type : "unknown",
845
+ required: required.has(name),
846
+ description: property.description,
847
+ ...isRecord(property.items) ? { items: property.items } : {},
848
+ ...typeof property.minItems === "number" ? { minItems: property.minItems } : {},
849
+ ...typeof property.maxItems === "number" ? { maxItems: property.maxItems } : {},
850
+ ...Object.prototype.hasOwnProperty.call(property, "default") ? { default: property.default } : {}
851
+ };
852
+ });
853
+ }
854
+ function toolOutputFieldsForDisplay(outputSchema) {
855
+ if (Object.keys(outputSchema).length === 0) return [];
856
+ return recursiveToolInputFieldsForDisplay({
857
+ jsonSchema: outputSchema
858
+ }).filter(
859
+ (field) => typeof field.name === "string" && field.name.includes("[]")
860
+ );
861
+ }
862
+ function canonicalToolJsonSchema(inputSchema) {
863
+ return isRecord(inputSchema.jsonSchema) ? inputSchema.jsonSchema : inputSchema;
864
+ }
865
+ function publicToolInputSchemaForDescribe(inputSchema) {
866
+ const exposesProviderSpend = (description) => {
867
+ const withoutDeeplineCredits = description.replace(
868
+ /\bdeepline(?:-facing)?\s+credits?\b/gi,
869
+ ""
870
+ );
871
+ return /\bcredits?\b/i.test(withoutDeeplineCredits) || /\bprovider\s+(?:cost|spend|price|pricing|usage)\b/i.test(
872
+ withoutDeeplineCredits
873
+ ) || /\b(?:costs?|charges?|priced at)\s+[$€£]\s*\d/i.test(
874
+ withoutDeeplineCredits
875
+ ) || /\b(?:costs?|charges?|priced at)\s+\d+(?:\.\d+)?\s*(?:usd|eur|gbp)\b/i.test(
876
+ withoutDeeplineCredits
877
+ ) || /\battribute-priced\b/i.test(withoutDeeplineCredits) || /\b(?:cost|price|pricing)\s+(?:grows?|increases?|scales?|varies?)\b/i.test(
878
+ withoutDeeplineCredits
879
+ ) || /\b(?:will be|are|is|be)\s+(?:billed|charged)\b/i.test(
880
+ withoutDeeplineCredits
881
+ ) || /\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);
882
+ };
883
+ const stripDescriptions = (value2) => {
884
+ if (Array.isArray(value2)) return value2.map(stripDescriptions);
885
+ if (!isRecord(value2)) return value2;
886
+ return Object.fromEntries(
887
+ Object.entries(value2).flatMap(([key, nested]) => {
888
+ if (key === "description" && typeof nested === "string" && exposesProviderSpend(nested)) {
889
+ return [];
890
+ }
891
+ return [[key, stripDescriptions(nested)]];
892
+ })
893
+ );
894
+ };
895
+ return stripDescriptions(inputSchema);
896
+ }
897
+ function recursiveToolInputFieldsForDisplay(inputSchema) {
898
+ const root = canonicalToolJsonSchema(inputSchema);
899
+ const fields = /* @__PURE__ */ new Map();
900
+ const schemasById = /* @__PURE__ */ new Map();
901
+ const collectSchemaIds = (value2) => {
902
+ if (Array.isArray(value2)) {
903
+ for (const item of value2) collectSchemaIds(item);
904
+ return;
905
+ }
906
+ if (!isRecord(value2)) return;
907
+ if (typeof value2.$id === "string" && value2.$id.trim()) {
908
+ schemasById.set(value2.$id.trim(), value2);
909
+ }
910
+ for (const nested of Object.values(value2)) collectSchemaIds(nested);
911
+ };
912
+ collectSchemaIds(root);
913
+ const resolveRef = (schema) => {
914
+ const ref = typeof schema.$ref === "string" ? schema.$ref : "";
915
+ if (!ref.startsWith("#/")) return schemasById.get(ref) ?? schema;
916
+ let current = root;
917
+ for (const rawSegment of ref.slice(2).split("/")) {
918
+ const segment = rawSegment.replace(/~1/g, "/").replace(/~0/g, "~");
919
+ if (!isRecord(current)) return schema;
920
+ current = current[segment];
921
+ }
922
+ return isRecord(current) ? current : schema;
923
+ };
924
+ const addField = (field) => {
925
+ const name = typeof field.name === "string" ? field.name : "";
926
+ if (!name) return;
927
+ const existing = fields.get(name);
928
+ if (!existing || existing.type === "unknown") {
929
+ fields.set(name, field);
930
+ }
931
+ };
932
+ const visit = (unresolvedSchema, path, required, activeRefs = /* @__PURE__ */ new Set()) => {
933
+ const ref = typeof unresolvedSchema.$ref === "string" ? unresolvedSchema.$ref : "";
934
+ if (ref && activeRefs.has(ref)) return;
935
+ const schema = resolveRef(unresolvedSchema);
936
+ const nextActiveRefs = ref ? /* @__PURE__ */ new Set([...activeRefs, ref]) : activeRefs;
937
+ 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";
938
+ if (path) {
939
+ addField({
940
+ name: path,
941
+ type,
942
+ required,
943
+ description: schema.description,
944
+ ...Array.isArray(schema.enum) ? { enum: schema.enum } : {},
945
+ ...isRecord(schema.items) ? { items: schema.items } : {},
946
+ ...typeof schema.minItems === "number" ? { minItems: schema.minItems } : {},
947
+ ...typeof schema.maxItems === "number" ? { maxItems: schema.maxItems } : {},
948
+ ...Object.prototype.hasOwnProperty.call(schema, "default") ? { default: schema.default } : {}
949
+ });
950
+ }
951
+ const properties = isRecord(schema.properties) ? schema.properties : {};
952
+ const requiredNames = new Set(
953
+ Array.isArray(schema.required) ? schema.required.map(String) : []
954
+ );
955
+ for (const [name, value2] of Object.entries(properties)) {
956
+ if (!isRecord(value2)) continue;
957
+ visit(
958
+ value2,
959
+ path ? `${path}.${name}` : name,
960
+ requiredNames.has(name),
961
+ nextActiveRefs
962
+ );
963
+ }
964
+ if (isRecord(schema.items)) {
965
+ visit(schema.items, `${path}[]`, false, nextActiveRefs);
966
+ }
967
+ for (const keyword of ["anyOf", "oneOf", "allOf"]) {
968
+ const branches = Array.isArray(schema[keyword]) ? schema[keyword] : [];
969
+ for (const branch of branches) {
970
+ if (isRecord(branch)) {
971
+ visit(branch, path, required, nextActiveRefs);
972
+ }
973
+ }
974
+ }
975
+ };
976
+ visit(root, "", false);
977
+ return fields.size ? [...fields.values()] : toolInputFieldsForDisplay(inputSchema);
978
+ }
979
+ function inputFieldJsonForDescribe(field) {
980
+ const publicItems = isRecord(field.items) ? publicToolInputSchemaForDescribe({ items: field.items }).items : void 0;
981
+ return {
982
+ name: field.name,
983
+ type: field.type ?? "unknown",
984
+ required: Boolean(field.required),
985
+ ...field.description ? { description: field.description } : {},
986
+ ...isRecord(publicItems) ? { items: publicItems } : {},
987
+ ...typeof field.minItems === "number" ? { minItems: field.minItems } : {},
988
+ ...typeof field.maxItems === "number" ? { maxItems: field.maxItems } : {},
989
+ ...Object.prototype.hasOwnProperty.call(field, "default") ? { default: field.default } : {}
990
+ };
991
+ }
992
+ function isRecord(value2) {
993
+ return Boolean(value2 && typeof value2 === "object" && !Array.isArray(value2));
994
+ }
995
+ function stringField(source, ...keys) {
996
+ for (const key of keys) {
997
+ const value2 = source[key];
998
+ if (typeof value2 === "string" && value2.trim()) return value2.trim();
999
+ }
1000
+ return "";
1001
+ }
1002
+ function arrayField(source, ...keys) {
1003
+ for (const key of keys) {
1004
+ const value2 = source[key];
1005
+ if (Array.isArray(value2)) return value2;
1006
+ }
1007
+ return [];
1008
+ }
1009
+ function recordField(source, ...keys) {
1010
+ for (const key of keys) {
1011
+ const value2 = source[key];
1012
+ if (isRecord(value2)) return value2;
1013
+ }
1014
+ return {};
1015
+ }
1016
+ function starterScriptJson(script) {
1017
+ return {
1018
+ path: script.path,
1019
+ sourceCode: script.sourceCode,
1020
+ projectDir: script.projectDir,
1021
+ copyToProject: {
1022
+ macosLinux: script.macCopyCommand,
1023
+ windowsPowerShell: script.windowsCopyCommand
1024
+ }
1025
+ };
1026
+ }
1027
+
1028
+ // ../plays/tool-category-descriptions.ts
1029
+ var TOOL_CATEGORY_DESCRIPTIONS = {
1030
+ company_search: "Find companies matching firmographic, ad, or web criteria.",
1031
+ people_search: "Find people matching role, company, or persona criteria.",
1032
+ people_enrich: "Enrich a known person with contact, social, and profile data.",
1033
+ company_enrich: "Enrich a known company with firmographic and account data.",
1034
+ email_finder: "Find work or personal email addresses for a person.",
1035
+ email_verify: "Validate email deliverability and catch-all status.",
1036
+ phone_finder: "Find mobile or direct phone numbers for a person.",
1037
+ phone_verify: "Validate phone-number reachability and line type.",
1038
+ research: "Research accounts, people, news, and signals for context and scoring.",
1039
+ autocomplete: "Resolve names and entities to canonical catalog records.",
1040
+ automation: "Kick off provider-side jobs, exports, and asynchronous workflows.",
1041
+ outbound_tools: "Run outbound sequencing, deliverability, and campaign operations.",
1042
+ admin: "Provider-side status, metadata, and account operations behind other tools.",
1043
+ smb: "Look up small-business listings, local records, and public filings.",
1044
+ identity_resolution: "Match a partial identity to a single resolved person or company.",
1045
+ reverse_lookup: "Resolve an email, phone, or profile back to a person.",
1046
+ enrichment: "General-purpose record enrichment across people and companies.",
1047
+ batch: "Run an enrichment or search operation over many rows at once.",
1048
+ premium: "Higher-cost tools with premium provider coverage.",
1049
+ free: "Free tools that do not spend Deepline credits."
1050
+ };
1051
+ var WELL_KNOWN_TOOL_CATEGORIES = Object.freeze(
1052
+ Object.keys(TOOL_CATEGORY_DESCRIPTIONS)
1053
+ );
1054
+ function describeToolCategory(category) {
1055
+ return TOOL_CATEGORY_DESCRIPTIONS[category] ?? null;
1056
+ }
1057
+
1058
+ // src/cli/commands/model-description.ts
1059
+ function formatModelDescription(description) {
1060
+ const lines = [];
1061
+ lines.push(description.model);
1062
+ lines.push(`Provider: ${description.provider}`);
1063
+ const name = stringField2(description.modelMetadata, "name");
1064
+ if (name) lines.push(`Name: ${name}`);
1065
+ const contextWindow = numberField(
1066
+ description.modelMetadata,
1067
+ "context_window"
1068
+ );
1069
+ if (contextWindow !== null) lines.push(`Context: ${contextWindow}`);
1070
+ const tags = arrayField2(description.modelMetadata, "tags").filter(
1071
+ (value2) => typeof value2 === "string"
1072
+ );
1073
+ if (tags.length) lines.push(`Tags: ${tags.join(", ")}`);
1074
+ lines.push("");
1075
+ lines.push("Provider options:");
1076
+ appendNamespace(lines, description.providerOptions.gateway);
1077
+ if (description.providerOptions.selectedProvider) {
1078
+ appendNamespace(lines, description.providerOptions.selectedProvider);
1079
+ }
1080
+ lines.push("");
1081
+ lines.push("Example input:");
1082
+ lines.push(JSON.stringify(description.exampleInput, null, 2));
1083
+ if (description.caveats.length) {
1084
+ lines.push("");
1085
+ lines.push("Caveats:");
1086
+ for (const caveat of description.caveats) {
1087
+ lines.push(`- ${caveat}`);
1088
+ }
1089
+ }
1090
+ return `${lines.join("\n")}
1091
+ `;
1092
+ }
1093
+ function appendNamespace(lines, namespace) {
1094
+ lines.push(`- ${namespace.provider} (${namespace.sourceSymbol})`);
1095
+ for (const field of namespace.fields) {
1096
+ const values = field.enumValues?.length ? ` (${field.enumValues.map((value2) => JSON.stringify(value2)).join(" | ")})` : "";
1097
+ lines.push(
1098
+ ` - ${field.name}: ${field.type}${values} - ${field.description}`
1099
+ );
1100
+ }
1101
+ }
1102
+ function stringField2(value2, key) {
1103
+ if (!value2 || typeof value2 !== "object" || Array.isArray(value2)) return null;
1104
+ const candidate = value2[key];
1105
+ return typeof candidate === "string" && candidate.trim() ? candidate.trim() : null;
1106
+ }
1107
+ function numberField(value2, key) {
1108
+ if (!value2 || typeof value2 !== "object" || Array.isArray(value2)) return null;
1109
+ const candidate = value2[key];
1110
+ return typeof candidate === "number" ? candidate : null;
1111
+ }
1112
+ function arrayField2(value2, key) {
1113
+ if (!value2 || typeof value2 !== "object" || Array.isArray(value2)) return [];
1114
+ const candidate = value2[key];
1115
+ return Array.isArray(candidate) ? candidate : [];
1116
+ }
1117
+
1118
+ // src/cli/tool-connection-status.ts
1119
+ function toolConnectionStatusMessage(input) {
1120
+ if (input.credentialStatus === "requires_connection") {
1121
+ return "requires your credentials \u2014 not connected (connect to use)";
1122
+ }
1123
+ if (input.connected === false && input.credentialStatus === "managed") {
1124
+ return "temporarily unavailable";
1125
+ }
1126
+ return null;
1127
+ }
1128
+
1129
+ // src/cli/commands/tools.ts
1130
+ var TOOL_COMMAND_TEMPLATES = {
1131
+ describe: "deepline describe <toolId>",
1132
+ execute: "deepline tools execute <toolId> --input '{...}'"
1133
+ };
1134
+ function toListedTool(tool) {
1135
+ if (isPlayLikeTool(tool)) {
1136
+ return {
1137
+ ...tool,
1138
+ description: listedToolDescription(tool),
1139
+ id: tool.toolId,
1140
+ type: "play",
1141
+ executeCommand: playRunCommandForTool(tool, tool.toolId)
1142
+ };
1143
+ }
1144
+ return {
1145
+ ...tool,
1146
+ description: listedToolDescription(tool),
1147
+ id: tool.toolId,
1148
+ type: "tool",
1149
+ executeCommand: `deepline tools execute ${tool.toolId}`
1150
+ };
1151
+ }
1152
+ function normalizeGrepText(value2) {
1153
+ if (value2 === null || value2 === void 0) return "";
1154
+ if (typeof value2 === "string") return value2.toLowerCase();
1155
+ if (typeof value2 === "number" || typeof value2 === "boolean") {
1156
+ return String(value2).toLowerCase();
1157
+ }
1158
+ if (Array.isArray(value2)) return value2.map(normalizeGrepText).join(" ");
1159
+ if (typeof value2 === "object") {
1160
+ return Object.values(value2).map(normalizeGrepText).join(" ");
1161
+ }
1162
+ return "";
1163
+ }
1164
+ function parseGrepTerms(query, mode) {
1165
+ const trimmed = query.trim().toLowerCase();
1166
+ if (!trimmed) return [];
1167
+ if (mode === "phrase") return [trimmed];
511
1168
  const matches = trimmed.match(/"([^"]+)"|'([^']+)'|\S+/g) ?? [];
512
1169
  return matches.map((term) => term.replace(/^["']|["']$/g, "").trim()).filter(Boolean);
513
1170
  }
@@ -591,7 +1248,7 @@ function requiredInputIds(tool) {
591
1248
  }
592
1249
  function notConnectedSuffix(tool) {
593
1250
  const record = tool;
594
- const status = stringField2(record, "credentialStatus", "credential_status");
1251
+ const status = stringField(record, "credentialStatus", "credential_status");
595
1252
  const connected = record.connected;
596
1253
  const message = toolConnectionStatusMessage({
597
1254
  connected: connected === false ? false : void 0,
@@ -605,13 +1262,13 @@ function shortPricingHint(tool) {
605
1262
  "pricing"
606
1263
  );
607
1264
  const credits = numberField2(pricing, "creditsPerUnit", "credits_per_unit");
608
- const unit = stringField2(pricing, "unit");
1265
+ const unit = stringField(pricing, "unit");
609
1266
  if (credits !== null) {
610
1267
  return `${formatDecimal(credits)} cr/${unit || "unit"}`;
611
1268
  }
612
- const summary = stringField2(pricing, "summary");
1269
+ const summary = stringField(pricing, "summary");
613
1270
  if (summary) return summary;
614
- const displayText = stringField2(pricing, "displayText", "display_text");
1271
+ const displayText = stringField(pricing, "displayText", "display_text");
615
1272
  return displayText || null;
616
1273
  }
617
1274
  function aggregateCategorySummaries(tools) {
@@ -943,34 +1600,6 @@ Inspect its schema with: deepline describe ${playName}`;
943
1600
  function printPlayAliasToolError(toolId, play) {
944
1601
  console.error(playAliasToolErrorMessage(toolId, play));
945
1602
  }
946
- function isPlayLikeTool(tool) {
947
- const record = tool;
948
- if (record.isPlay === true || record.is_play === true) return true;
949
- const playExpansion = recordField(record, "playExpansion", "play_expansion");
950
- if (Object.keys(playExpansion).length > 0) return true;
951
- const toolId = typeof record.toolId === "string" ? record.toolId : "";
952
- return toolId.endsWith("_waterfall");
953
- }
954
- function isMonitorTypeTool(tool) {
955
- return stringField2(tool, "kind") === "monitor_type";
956
- }
957
- function playReferenceForTool(tool) {
958
- const record = tool;
959
- const declared = stringField2(record, "playReference", "play_reference");
960
- if (declared.startsWith("prebuilt/")) {
961
- return declared;
962
- }
963
- return null;
964
- }
965
- function playSearchCommandForToolId(toolId) {
966
- return `deepline search --type prebuilts ${JSON.stringify(toolId.replace(/_/g, " "))}`;
967
- }
968
- function playRunCommandForTool(tool, toolId, input) {
969
- const playReference = playReferenceForTool(tool);
970
- if (!playReference) return playSearchCommandForToolId(toolId);
971
- const inputArg = input === void 0 ? "'{...}'" : `'${JSON.stringify(input)}'`;
972
- return `deepline plays run ${playReference} --input ${inputArg}`;
973
- }
974
1603
  function playLikeToolExecuteErrorMessage(toolId, tool) {
975
1604
  const playReference = tool ? playReferenceForTool(tool) : null;
976
1605
  const nextStep = playReference ? `Use: deepline plays run ${playReference} --input '{...}'` : `Find the maintained workflow with: ${playSearchCommandForToolId(toolId)}`;
@@ -1188,7 +1817,7 @@ Examples:
1188
1817
  process.exitCode = await narrowView();
1189
1818
  return;
1190
1819
  }
1191
- const { describeAnything } = await import("./describe-DBRY5BNK.mjs");
1820
+ const { describeAnything } = await import("./describe-6O2ENKTP.mjs");
1192
1821
  process.exitCode = await describeAnything(
1193
1822
  toolId,
1194
1823
  {
@@ -1345,7 +1974,12 @@ async function getTool(toolId, options = {}, compatibilityMetadata) {
1345
1974
  return 0;
1346
1975
  }
1347
1976
  if ((options.schemaOnly || options.examplesOnly || options.gettersOnly) && !isMonitorTypeTool(tool) && !isPlayLikeTool(tool) && (options.json || options.contractJson)) {
1348
- const contract = toolContractJsonForDescribe(tool, toolId);
1977
+ const contract = toolContractJsonForDescribe(
1978
+ tool,
1979
+ toolId,
1980
+ void 0,
1981
+ seedToolListScript
1982
+ );
1349
1983
  printCompactJson({
1350
1984
  toolId: contract.toolId,
1351
1985
  ...options.schemaOnly ? {
@@ -1370,7 +2004,12 @@ async function getTool(toolId, options = {}, compatibilityMetadata) {
1370
2004
  }
1371
2005
  if (options.contractJson) {
1372
2006
  printCompactJson({
1373
- ...toolContractJsonForDescribe(tool, toolId),
2007
+ ...toolContractJsonForDescribe(
2008
+ tool,
2009
+ toolId,
2010
+ void 0,
2011
+ seedToolListScript
2012
+ ),
1374
2013
  ...modelDescription ? { modelOptions: modelDescription } : {},
1375
2014
  ...inferenceQuote ? { inferenceQuote } : {}
1376
2015
  });
@@ -1379,7 +2018,7 @@ async function getTool(toolId, options = {}, compatibilityMetadata) {
1379
2018
  const emitJson = options.json === true;
1380
2019
  if (emitJson) {
1381
2020
  printCompactJson({
1382
- ...toolMetadataJsonForDescribe(tool, toolId),
2021
+ ...toolMetadataJsonForDescribe(tool, toolId, seedToolListScript),
1383
2022
  ...modelDescription ? { modelOptions: modelDescription } : {},
1384
2023
  ...inferenceQuote ? { inferenceQuote } : {}
1385
2024
  });
@@ -1393,149 +2032,46 @@ async function getTool(toolId, options = {}, compatibilityMetadata) {
1393
2032
  if (options.examplesOnly) {
1394
2033
  printToolExamplesOnly(tool, toolId);
1395
2034
  if (inferenceQuote) printInferenceQuoteSummary(inferenceQuote);
1396
- return 0;
1397
- }
1398
- if (options.gettersOnly) {
1399
- printToolGettersOnly(tool, toolId);
1400
- if (inferenceQuote) printInferenceQuoteSummary(inferenceQuote);
1401
- return 0;
1402
- }
1403
- if (options.compact) {
1404
- printCompactToolContract(tool, toolId);
1405
- if (modelDescription) {
1406
- process.stdout.write(`
1407
- ${formatModelDescription(modelDescription)}`);
1408
- }
1409
- if (inferenceQuote) printInferenceQuoteSummary(inferenceQuote);
1410
- return 0;
1411
- }
1412
- printCompactToolContract(tool, toolId);
1413
- if (modelDescription) {
1414
- process.stdout.write(`
1415
- ${formatModelDescription(modelDescription)}`);
1416
- }
1417
- if (inferenceQuote) printInferenceQuoteSummary(inferenceQuote);
1418
- return 0;
1419
- }
1420
- function inferenceQuoteSummaryLines(_quote) {
1421
- return [
1422
- "",
1423
- "Inference quote:",
1424
- "- Temporary hold: priced estimate (minimum 0.02 credits)",
1425
- "- Final charge: actual usage"
1426
- ];
1427
- }
1428
- function printInferenceQuoteSummary(quote) {
1429
- for (const line of inferenceQuoteSummaryLines(quote)) console.log(line);
1430
- }
1431
- function toolContractJsonForDescribe(tool, requestedToolId, authoringContractEdition) {
1432
- const toolId = String(tool.toolId || requestedToolId);
1433
- const inputFields = toolInputFieldsForDisplay(
1434
- recordField(tool, "inputSchema", "input_schema")
1435
- );
1436
- const inputSchema = publicToolInputSchemaForDescribe(
1437
- recordField(tool, "inputSchema", "input_schema")
1438
- );
1439
- const outputSchemaRecord = recordField(tool, "outputSchema", "output_schema");
1440
- const outputFields = toolOutputFieldsForDisplay(outputSchemaRecord);
1441
- const usageGuidance = recordField(tool, "usageGuidance", "usage_guidance");
1442
- const guidance = recordField(tool, "guidance");
1443
- const toolExecutionResult = recordField(
1444
- usageGuidance,
1445
- "toolExecutionResult",
1446
- "tool_execution_result"
1447
- );
1448
- const extractedLists = extractionContractEntries(
1449
- arrayField2(toolExecutionResult, "extractedLists", "extracted_lists")
1450
- ).map((entry) => ({
1451
- ...entry,
1452
- returnType: playToolListGetterMode(authoringContractEdition) === "array" ? "Array" : "PlayDataset",
1453
- rowsExpression: playToolListGetterMode(authoringContractEdition) === "array" ? entry.expression : `await ${entry.expression}.materialize()`
1454
- }));
1455
- const extractedValues = extractionContractEntries(
1456
- arrayField2(toolExecutionResult, "extractedValues", "extracted_values")
1457
- );
1458
- const pricing = Capability.fromCatalogEntry(tool).describe().customerCost();
1459
- const executionMetadataRecord = recordField(
1460
- tool,
1461
- "executionMetadata",
1462
- "execution_metadata"
1463
- );
1464
- const executionMetadata = Object.keys(executionMetadataRecord).length > 0 ? executionMetadataRecord : null;
1465
- const batchCapabilityRecord = recordField(
1466
- tool,
1467
- "batchCapability",
1468
- "batch_capability"
1469
- );
1470
- const batchCapability = Object.keys(batchCapabilityRecord).length > 0 ? batchCapabilityRecord : null;
1471
- const deprecation = recordField(tool, "deprecation");
1472
- const replacementToolId = stringField2(
1473
- deprecation,
1474
- "replacementToolId",
1475
- "replacement_tool_id"
1476
- );
1477
- const deprecationMessage = stringField2(deprecation, "message");
1478
- const deprecationExecution = stringField2(deprecation, "execution");
1479
- const deprecated = tool.deprecated === true || stringField2(tool, "credentialStatus", "credential_status") === "deprecated";
1480
- const starterScript = !deprecated && !isPlayLikeTool(tool) && extractedLists.length > 0 ? starterScriptJson(
1481
- seedToolListScript({
1482
- toolId,
1483
- payload: samplePayloadForInputFields(inputFields),
1484
- rows: []
1485
- })
1486
- ) : null;
1487
- const executeCommand = deprecated && replacementToolId ? `deepline tools execute ${replacementToolId} --input '{...}'` : isPlayLikeTool(tool) ? playRunCommandForTool(tool, toolId) : `deepline tools execute ${toolId} --input '{...}'`;
1488
- return {
1489
- schemaVersion: 1,
1490
- toolId,
1491
- provider: tool.provider,
1492
- displayName: tool.displayName,
1493
- cost: pricing,
1494
- description: tool.description,
1495
- ...Object.keys(guidance).length > 0 ? { guidance } : {},
1496
- categories: tool.categories,
1497
- ...Array.isArray(tool.requestWarnings) ? { requestWarnings: tool.requestWarnings } : {},
1498
- ...deprecated ? {
1499
- deprecated: true,
1500
- callable: tool.callable !== false,
1501
- deprecation: {
1502
- replacementToolId,
1503
- message: deprecationMessage,
1504
- ...deprecationExecution ? { execution: deprecationExecution } : {}
1505
- }
1506
- } : {},
1507
- inputFields: inputFields.map(inputFieldJsonForDescribe),
1508
- inputSchema,
1509
- ...isRecord(tool.responseSchema) ? { responseSchema: tool.responseSchema } : {},
1510
- ...Array.isArray(tool.examples) ? { examples: tool.examples } : {},
1511
- responseAccess: "result.toolResponse.rawV2",
1512
- ...Object.keys(outputSchemaRecord).length > 0 ? {
1513
- outputSchema: publicToolInputSchemaForDescribe(outputSchemaRecord),
1514
- outputFields: outputFields.map(inputFieldJsonForDescribe)
1515
- } : {},
1516
- ...executionMetadata ? { executionMetadata } : {},
1517
- ...batchCapability ? { batchCapability } : {},
1518
- getters: {
1519
- extractedLists,
1520
- extractedValues
1521
- },
1522
- executeCommand,
1523
- ...starterScript ? { starterScript } : {}
1524
- };
2035
+ return 0;
2036
+ }
2037
+ if (options.gettersOnly) {
2038
+ printToolGettersOnly(tool, toolId);
2039
+ if (inferenceQuote) printInferenceQuoteSummary(inferenceQuote);
2040
+ return 0;
2041
+ }
2042
+ if (options.compact) {
2043
+ printCompactToolContract(tool, toolId);
2044
+ if (modelDescription) {
2045
+ process.stdout.write(`
2046
+ ${formatModelDescription(modelDescription)}`);
2047
+ }
2048
+ if (inferenceQuote) printInferenceQuoteSummary(inferenceQuote);
2049
+ return 0;
2050
+ }
2051
+ printCompactToolContract(tool, toolId);
2052
+ if (modelDescription) {
2053
+ process.stdout.write(`
2054
+ ${formatModelDescription(modelDescription)}`);
2055
+ }
2056
+ if (inferenceQuote) printInferenceQuoteSummary(inferenceQuote);
2057
+ return 0;
1525
2058
  }
1526
- function extractionContractEntries(entries) {
1527
- return entries.flatMap((entry) => {
1528
- if (!isRecord(entry)) return [];
1529
- const name = stringField2(entry, "name");
1530
- const expression = stringField2(entry, "expression");
1531
- return name && expression ? [{ name, expression }] : [];
1532
- });
2059
+ function inferenceQuoteSummaryLines(_quote) {
2060
+ return [
2061
+ "",
2062
+ "Inference quote:",
2063
+ "- Temporary hold: priced estimate (minimum 0.02 credits)",
2064
+ "- Final charge: actual usage"
2065
+ ];
2066
+ }
2067
+ function printInferenceQuoteSummary(quote) {
2068
+ for (const line of inferenceQuoteSummaryLines(quote)) console.log(line);
1533
2069
  }
1534
2070
  function printMonitorTypeFilters(tool) {
1535
2071
  const schema = recordField(tool, "payload_schema", "payloadSchema");
1536
2072
  const properties = recordField(schema, "properties");
1537
2073
  const required = new Set(
1538
- arrayField2(schema, "required").filter(
2074
+ arrayField(schema, "required").filter(
1539
2075
  (v) => typeof v === "string"
1540
2076
  )
1541
2077
  );
@@ -1548,11 +2084,11 @@ function printMonitorTypeFilters(tool) {
1548
2084
  for (const name of names) {
1549
2085
  const field = isRecord(properties[name]) ? properties[name] : {};
1550
2086
  const star = required.has(name) ? "*" : "";
1551
- const enumVals = arrayField2(field, "enum").filter(
2087
+ const enumVals = arrayField(field, "enum").filter(
1552
2088
  (v) => typeof v === "string"
1553
2089
  );
1554
- const type = enumVals.length ? `one of [${enumVals.join(", ")}]` : stringField2(field, "type") || "string";
1555
- const desc = stringField2(field, "description");
2090
+ const type = enumVals.length ? `one of [${enumVals.join(", ")}]` : stringField(field, "type") || "string";
2091
+ const desc = stringField(field, "description");
1556
2092
  console.log(`- ${name}${star}: ${type}${desc ? ` - ${desc}` : ""}`);
1557
2093
  }
1558
2094
  }
@@ -1561,260 +2097,96 @@ function printMonitorTypeFilterExamples(tool) {
1561
2097
  const fields = recordField(documentation, "fields");
1562
2098
  const examples = Object.entries(fields).flatMap(([name, rawField]) => {
1563
2099
  const grammar = recordField(isRecord(rawField) ? rawField : {}, "grammar");
1564
- const example = stringField2(grammar, "example");
2100
+ const example = stringField(grammar, "example");
1565
2101
  const values = [
1566
- ...arrayField2(grammar, "examples").filter(
2102
+ ...arrayField(grammar, "examples").filter(
1567
2103
  (value2) => typeof value2 === "string" && Boolean(value2)
1568
2104
  ),
1569
- ...example ? [example] : []
1570
- ];
1571
- return [...new Set(values)].map((example2) => ({ name, example: example2 }));
1572
- });
1573
- if (examples.length === 0) return;
1574
- console.log("");
1575
- console.log("Filter examples:");
1576
- for (const { name, example } of examples) {
1577
- console.log(`- ${name}: ${example}`);
1578
- }
1579
- }
1580
- function printMonitorTypeStreams(tool) {
1581
- const streams = arrayField2(tool, "streams", "output_streams").filter(
1582
- isRecord
1583
- );
1584
- if (!streams.length) return;
1585
- console.log("");
1586
- console.log("Filter columns (a play's sqlListeners.where, per stream):");
1587
- for (const stream of streams) {
1588
- const name = stringField2(stream, "stream");
1589
- const cols = arrayField2(stream, "columns").filter(isRecord).map((col) => stringField2(col, "name")).filter(Boolean);
1590
- console.log(`- ${name}: ${cols.join(", ")}`);
1591
- }
1592
- }
1593
- function monitorTypePricingLines(tool) {
1594
- const pricing = recordField(tool, "pricing");
1595
- const byType = recordField(
1596
- pricing,
1597
- "pricing_by_radar_type",
1598
- "pricingByRadarType"
1599
- );
1600
- const keys = Object.keys(byType);
1601
- if (!keys.length) {
1602
- return ["Pricing: Deepline credits per accepted event"];
1603
- }
1604
- const lines = ["Pricing (Deepline credits per accepted event):"];
1605
- for (const key of keys) {
1606
- const entry = isRecord(byType[key]) ? byType[key] : {};
1607
- const credits = numberField2(entry, "deepline_credits", "deeplineCredits");
1608
- const display = stringField2(entry, "display");
1609
- const shown = display || (credits !== null ? `${formatDecimal(credits)} credits/event` : "not listed");
1610
- lines.push(`- ${key}: ${shown}`);
1611
- }
1612
- return lines;
1613
- }
1614
- function printMonitorTypePricing(tool) {
1615
- for (const line of monitorTypePricingLines(tool)) console.log(line);
1616
- }
1617
- function printMonitorTypeDeploy(tool) {
1618
- const deploy = recordField(tool, "deploy");
1619
- const toolId = stringField2(tool, "toolId");
1620
- const example = stringField2(deploy, "example") || `deepline monitors deploy '{"key":"...","tool":"${toolId}","payload":{...}}'`;
1621
- console.log("Deploy (a monitor type is deployed, not executed):");
1622
- console.log(` ${example}`);
1623
- }
1624
- function printMonitorTypeContract(tool, requestedToolId) {
1625
- const toolId = stringField2(tool, "toolId") || requestedToolId;
1626
- console.log(toolId);
1627
- const displayName = stringField2(tool, "displayName");
1628
- if (displayName) console.log(`Best for: ${displayName}`);
1629
- const description = stringField2(tool, "description");
1630
- if (description) console.log(`Description: ${description}`);
1631
- const categories = arrayField2(tool, "categories").filter(
1632
- (v) => typeof v === "string"
1633
- );
1634
- if (categories.length) console.log(`Tags: ${categories.join(", ")}`);
1635
- console.log("");
1636
- console.log(
1637
- "Monitor type \u2014 streams a provider's events into your warehouse. Deploy it, don't execute it."
1638
- );
1639
- console.log("");
1640
- printMonitorTypeFilters(tool);
1641
- printMonitorTypeFilterExamples(tool);
1642
- printMonitorTypeStreams(tool);
1643
- console.log("");
1644
- printMonitorTypePricing(tool);
1645
- console.log("");
1646
- printMonitorTypeDeploy(tool);
1647
- console.log("");
1648
- console.log(`More: deepline describe ${toolId}`);
1649
- }
1650
- function schemaNodeAt(schema, path) {
1651
- let node = schema;
1652
- for (const part of path.split(".").filter(Boolean)) {
1653
- const [key, ...indexes] = part.split("[");
1654
- node = recordField(isRecord(node) ? node : {}, "properties")[key];
1655
- for (const _index of indexes)
1656
- node = isRecord(node) ? node.items : void 0;
1657
- }
1658
- return node;
1659
- }
1660
- var NAMED_VALUE_SHAPES = {
1661
- email_status: { shape: "EmailStatus", schema: EMAIL_STATUS_JSON_SCHEMA },
1662
- job_change: { shape: "JobChange", schema: JOB_CHANGE_JSON_SCHEMA }
1663
- };
1664
- function extractorValueType(name) {
1665
- if (!isDeeplineExtractorTarget(name)) return void 0;
1666
- const definition = DEEPLINE_EXTRACTOR_TARGET_DEFINITIONS[name];
1667
- if (definition.enum) {
1668
- return {
1669
- type: definition.enum.map((value2) => JSON.stringify(value2)).join(" | ")
1670
- };
1671
- }
1672
- const named = NAMED_VALUE_SHAPES[definition.valueKind];
1673
- if (!named) return { type: "string" };
1674
- const { type, fields } = schemaField(name, named.schema, true);
1675
- return { type, ...fields ? { fields } : {}, shape: named.shape };
1676
- }
1677
- function jsonSchemaOf(wrapper) {
1678
- return isRecord(wrapper.jsonSchema) ? wrapper.jsonSchema : wrapper;
1679
- }
1680
- function publicToolSchemas(tool) {
1681
- const scrubbed = (...keys) => {
1682
- const schema = recordField(tool, ...keys);
1683
- if (Object.keys(schema).length === 0) return null;
1684
- const cleaned = publicToolInputSchemaForDescribe(schema);
1685
- return isRecord(cleaned.jsonSchema) ? cleaned.jsonSchema : cleaned;
1686
- };
1687
- const responseSchema = scrubbed("responseSchema", "response_schema");
1688
- return {
1689
- inputSchema: scrubbed(
1690
- "inputSchema",
1691
- "input_schema",
1692
- "payload_schema",
1693
- "payloadSchema"
1694
- ),
1695
- outputSchema: scrubbed("outputSchema", "output_schema"),
1696
- ...responseSchema ? { responseSchema } : {}
1697
- };
1698
- }
1699
- function describedTool(tool, requestedToolId) {
1700
- const id = stringField2(tool, "toolId") || requestedToolId;
1701
- const displayName = stringField2(tool, "displayName") || void 0;
1702
- const description = stringField2(tool, "bestFor", "best_for") || stringField2(tool, "description") || void 0;
1703
- if (isMonitorTypeTool(tool)) {
1704
- return {
1705
- kind: "monitor_type",
1706
- id,
1707
- displayName,
1708
- description,
1709
- cost: stringField2(recordField(tool, "pricing"), "displayText") || void 0,
1710
- guidance: [],
1711
- inputs: schemaFields(
1712
- recordField(tool, "payload_schema", "payloadSchema")
1713
- ),
1714
- outputs: [],
1715
- runner: {
1716
- via: "monitor",
1717
- deploy: stringField2(recordField(tool, "deploy"), "example") || `deepline monitors deploy '{"key":"...","tool":"${id}","payload":{...}}'`
1718
- }
1719
- };
1720
- }
1721
- const contract = toolContractJsonForDescribe(tool, requestedToolId);
1722
- const cost = recordField(contract, "cost");
1723
- const billing = stringField2(cost, "billingSourceLabel");
1724
- const deprecation = recordField(contract, "deprecation");
1725
- const getters = recordField(contract, "getters");
1726
- const outputSchema = jsonSchemaOf(recordField(contract, "outputSchema"));
1727
- const toolResult = recordField(tool, "toolResult", "tool_result");
1728
- const getterDetails = (kind) => new Map(
1729
- arrayField2(toolResult, kind).filter(isRecord).map((item) => [
1730
- stringField2(item, "name"),
1731
- recordField(item, "details")
1732
- ])
1733
- );
1734
- const declared = recordField(tool, "extractors");
1735
- const getterOutputs = (kind, roots) => {
1736
- const details = getterDetails(kind);
1737
- return arrayField2(getters, kind).filter(isRecord).map((entry) => {
1738
- const name = stringField2(entry, "name");
1739
- const rawPaths = arrayField2(
1740
- details.get(name) ?? {},
1741
- "rawToolOutputPaths"
1742
- ).map(String);
1743
- const paths = rawPaths.map(
1744
- (path) => path.replace(/^toolResponse\.raw\./, "")
1745
- );
1746
- const node = roots.flatMap((root) => paths.map((path) => schemaNodeAt(root, path))).find(isRecord);
1747
- const { fields, ...typed } = schemaField(name, node, true);
1748
- const valueType = stringField2(details.get(name) ?? {}, "valueType");
1749
- const deepline = kind === "extractedValues" ? extractorValueType(name) : void 0;
1750
- const known = typed.type !== "unknown" ? void 0 : kind === "extractedLists" ? { type: "object[]" } : deepline;
1751
- const means = kind === "extractedValues" ? fieldOfName(
1752
- name,
1753
- stringField2(declared[name] ?? {}, "means") || void 0
1754
- ) : void 0;
1755
- const field = {
1756
- ...typed,
1757
- ...means ? { means } : {},
1758
- // A normalized value has a named type instead of the response's
1759
- // shape; a normalized object is spelled out once under Types.
1760
- ...deepline?.shape ? deepline : valueType ? { type: valueType } : known ? known : fields ? { fields } : {},
1761
- // A list's row columns that matter are value getters of their own.
1762
- ...kind === "extractedLists" && fields ? { summarized: true } : {},
1763
- read: playResultExpression(entry),
1764
- ...rawPaths.length ? { paths: rawPaths } : {}
1765
- };
1766
- return { field, node };
1767
- });
1768
- };
1769
- const declaredLists = getterOutputs("extractedLists", [outputSchema]);
1770
- const lists = declaredLists.some(({ node }) => node) ? declaredLists.filter(({ node }) => node) : declaredLists;
1771
- const values = getterOutputs("extractedValues", [
1772
- outputSchema,
1773
- ...lists.map(({ node }) => node?.items)
1774
- ]).map((value2) => {
1775
- if (!lists.length || !value2.field.paths) return value2;
1776
- const within = value2.field.paths.map(
1777
- (path) => path.replace(/^toolResponse\.raw\./, "")
1778
- );
1779
- const list = lists.find(
1780
- ({ node }) => within.some((path) => isRecord(schemaNodeAt(node?.items, path)))
1781
- ) ?? lists[0];
1782
- return {
1783
- ...value2,
1784
- field: { ...value2.field, in: list.field.name, paths: within }
1785
- };
1786
- });
1787
- const playReference = isPlayLikeTool(tool) ? playReferenceForTool(tool) : null;
1788
- return {
1789
- kind: "tool",
1790
- id: String(contract.toolId),
1791
- displayName,
1792
- description,
1793
- cost: [
1794
- stringField2(cost, "displayText"),
1795
- // "Free (free)" says the same thing twice.
1796
- billing.toLowerCase() === stringField2(cost, "displayText").toLowerCase() ? "" : billing && `(${billing})`,
1797
- observedMaxText(cost) && `\u2014 ${observedMaxText(cost)}`
1798
- ].filter(Boolean).join(" ") || void 0,
1799
- guidance: [
1800
- ...contract.deprecated === true ? [`Deprecated. ${stringField2(deprecation, "message")}`.trim()] : [],
1801
- ...Object.values(recordField(contract, "guidance")).filter(
1802
- (line) => typeof line === "string" && /[a-z0-9]/i.test(line)
1803
- )
1804
- ],
1805
- rateLimit: rateLimitSummary(
1806
- recordField(contract, "executionMetadata").configuredRateLimits
1807
- ),
1808
- inputs: schemaFields(jsonSchemaOf(recordField(contract, "inputSchema"))),
1809
- outputs: [...lists, ...values].map(({ field }) => field),
1810
- rawResponse: schemaFields(outputSchema),
1811
- runner: playReference ? { via: "play", reference: playReference } : { via: "tool", toolId: String(contract.toolId) }
1812
- };
2105
+ ...example ? [example] : []
2106
+ ];
2107
+ return [...new Set(values)].map((example2) => ({ name, example: example2 }));
2108
+ });
2109
+ if (examples.length === 0) return;
2110
+ console.log("");
2111
+ console.log("Filter examples:");
2112
+ for (const { name, example } of examples) {
2113
+ console.log(`- ${name}: ${example}`);
2114
+ }
2115
+ }
2116
+ function printMonitorTypeStreams(tool) {
2117
+ const streams = arrayField(tool, "streams", "output_streams").filter(
2118
+ isRecord
2119
+ );
2120
+ if (!streams.length) return;
2121
+ console.log("");
2122
+ console.log("Filter columns (a play's sqlListeners.where, per stream):");
2123
+ for (const stream of streams) {
2124
+ const name = stringField(stream, "stream");
2125
+ const cols = arrayField(stream, "columns").filter(isRecord).map((col) => stringField(col, "name")).filter(Boolean);
2126
+ console.log(`- ${name}: ${cols.join(", ")}`);
2127
+ }
2128
+ }
2129
+ function monitorTypePricingLines(tool) {
2130
+ const pricing = recordField(tool, "pricing");
2131
+ const byType = recordField(
2132
+ pricing,
2133
+ "pricing_by_radar_type",
2134
+ "pricingByRadarType"
2135
+ );
2136
+ const keys = Object.keys(byType);
2137
+ if (!keys.length) {
2138
+ return ["Pricing: Deepline credits per accepted event"];
2139
+ }
2140
+ const lines = ["Pricing (Deepline credits per accepted event):"];
2141
+ for (const key of keys) {
2142
+ const entry = isRecord(byType[key]) ? byType[key] : {};
2143
+ const credits = numberField2(entry, "deepline_credits", "deeplineCredits");
2144
+ const display = stringField(entry, "display");
2145
+ const shown = display || (credits !== null ? `${formatDecimal(credits)} credits/event` : "not listed");
2146
+ lines.push(`- ${key}: ${shown}`);
2147
+ }
2148
+ return lines;
2149
+ }
2150
+ function printMonitorTypePricing(tool) {
2151
+ for (const line of monitorTypePricingLines(tool)) console.log(line);
2152
+ }
2153
+ function printMonitorTypeDeploy(tool) {
2154
+ const deploy = recordField(tool, "deploy");
2155
+ const toolId = stringField(tool, "toolId");
2156
+ const example = stringField(deploy, "example") || `deepline monitors deploy '{"key":"...","tool":"${toolId}","payload":{...}}'`;
2157
+ console.log("Deploy (a monitor type is deployed, not executed):");
2158
+ console.log(` ${example}`);
2159
+ }
2160
+ function printMonitorTypeContract(tool, requestedToolId) {
2161
+ const toolId = stringField(tool, "toolId") || requestedToolId;
2162
+ console.log(toolId);
2163
+ const displayName = stringField(tool, "displayName");
2164
+ if (displayName) console.log(`Best for: ${displayName}`);
2165
+ const description = stringField(tool, "description");
2166
+ if (description) console.log(`Description: ${description}`);
2167
+ const categories = arrayField(tool, "categories").filter(
2168
+ (v) => typeof v === "string"
2169
+ );
2170
+ if (categories.length) console.log(`Tags: ${categories.join(", ")}`);
2171
+ console.log("");
2172
+ console.log(
2173
+ "Monitor type \u2014 streams a provider's events into your warehouse. Deploy it, don't execute it."
2174
+ );
2175
+ console.log("");
2176
+ printMonitorTypeFilters(tool);
2177
+ printMonitorTypeFilterExamples(tool);
2178
+ printMonitorTypeStreams(tool);
2179
+ console.log("");
2180
+ printMonitorTypePricing(tool);
2181
+ console.log("");
2182
+ printMonitorTypeDeploy(tool);
2183
+ console.log("");
2184
+ console.log(`More: deepline describe ${toolId}`);
1813
2185
  }
1814
2186
  function toolGuidanceLines(guidance) {
1815
2187
  const record = isRecord(guidance) ? guidance : {};
1816
- const toolGuidance = stringField2(record, "tool");
1817
- const providerGuidance = stringField2(record, "provider");
2188
+ const toolGuidance = stringField(record, "tool");
2189
+ const providerGuidance = stringField(record, "provider");
1818
2190
  return [
1819
2191
  ...toolGuidance ? [`- This tool: ${toolGuidance}`] : [],
1820
2192
  ...providerGuidance ? [`- Provider: ${providerGuidance}`] : []
@@ -1825,7 +2197,12 @@ function printCompactToolContract(tool, requestedToolId) {
1825
2197
  printMonitorTypeContract(tool, requestedToolId);
1826
2198
  return;
1827
2199
  }
1828
- const contract = toolContractJsonForDescribe(tool, requestedToolId);
2200
+ const contract = toolContractJsonForDescribe(
2201
+ tool,
2202
+ requestedToolId,
2203
+ void 0,
2204
+ seedToolListScript
2205
+ );
1829
2206
  const cost = isRecord(contract.cost) ? contract.cost : {};
1830
2207
  const getters = isRecord(contract.getters) ? contract.getters : {};
1831
2208
  const listGetters = Array.isArray(getters.extractedLists) ? getters.extractedLists : [];
@@ -1849,8 +2226,8 @@ function printCompactToolContract(tool, requestedToolId) {
1849
2226
  printToolExecutionHints(contract);
1850
2227
  if (contract.deprecated === true) {
1851
2228
  const deprecation = isRecord(contract.deprecation) ? contract.deprecation : {};
1852
- const message = stringField2(deprecation, "message");
1853
- const replacementToolId = stringField2(
2229
+ const message = stringField(deprecation, "message");
2230
+ const replacementToolId = stringField(
1854
2231
  deprecation,
1855
2232
  "replacementToolId",
1856
2233
  "replacement_tool_id"
@@ -1876,11 +2253,11 @@ function printCompactToolContract(tool, requestedToolId) {
1876
2253
  console.log("Inputs:");
1877
2254
  for (const field of inputFields) {
1878
2255
  if (!isRecord(field)) continue;
1879
- const name = stringField2(field, "name");
2256
+ const name = stringField(field, "name");
1880
2257
  if (!name) continue;
1881
2258
  const required = field.required ? "*" : "";
1882
- const type = stringField2(field, "type") || "unknown";
1883
- const description = stringField2(field, "description");
2259
+ const type = stringField(field, "type") || "unknown";
2260
+ const description = stringField(field, "description");
1884
2261
  const enumValues = Array.isArray(field.enum) ? field.enum : [];
1885
2262
  const enumSuffix = enumValues.length ? ` enum=${enumValues.map(String).join("|")}` : "";
1886
2263
  const itemBoundsSuffix = arrayItemBoundsSuffix(field);
@@ -1896,7 +2273,7 @@ function printCompactToolContract(tool, requestedToolId) {
1896
2273
  console.log("");
1897
2274
  printToolExamplesOnly(tool, requestedToolId);
1898
2275
  const starterScript = isRecord(contract.starterScript) ? contract.starterScript : {};
1899
- const starterPath = stringField2(starterScript, "path");
2276
+ const starterPath = stringField(starterScript, "path");
1900
2277
  if (starterPath) {
1901
2278
  console.log("");
1902
2279
  console.log(`Starter script: ${starterPath}`);
@@ -1909,14 +2286,14 @@ function printCompactToolContract(tool, requestedToolId) {
1909
2286
  for (const entry of listGetters) {
1910
2287
  if (isRecord(entry))
1911
2288
  console.log(
1912
- `- ${stringField2(entry, "name")}: ${playResultExpression(entry)}`
2289
+ `- ${stringField(entry, "name")}: ${playResultExpression(entry)}`
1913
2290
  );
1914
2291
  }
1915
2292
  if (valueGetters.length) console.log("Values:");
1916
2293
  for (const entry of valueGetters) {
1917
2294
  if (isRecord(entry))
1918
2295
  console.log(
1919
- `- ${stringField2(entry, "name")}: ${playResultExpression(entry)}`
2296
+ `- ${stringField(entry, "name")}: ${playResultExpression(entry)}`
1920
2297
  );
1921
2298
  }
1922
2299
  }
@@ -1932,14 +2309,14 @@ function toolPricingOnlyLines(tool, requestedToolId, options = {}) {
1932
2309
  }
1933
2310
  const toolId = String(tool.toolId || requestedToolId);
1934
2311
  const cost = Capability.fromCatalogEntry(tool).describe().customerCost();
1935
- const pricingModel = stringField2(cost, "pricingModel") || "unknown";
1936
- const billing = stringField2(cost, "billingSourceLabel") || stringField2(cost, "billingSource") || stringField2(cost, "billingMode") || "unknown";
1937
- const explicitUnit = stringField2(cost, "unit");
2312
+ const pricingModel = stringField(cost, "pricingModel") || "unknown";
2313
+ const billing = stringField(cost, "billingSourceLabel") || stringField(cost, "billingSource") || stringField(cost, "billingMode") || "unknown";
2314
+ const explicitUnit = stringField(cost, "unit");
1938
2315
  const unit = explicitUnit || (pricingModel === "per_page" ? "page" : pricingModel === "per_result" ? "result" : pricingModel === "fixed" ? "call" : pricingModel.replace(/^per_/, "") || "unit");
1939
2316
  const credits = numberField2(cost, "deeplineCreditsPerPricingUnit");
1940
2317
  const usd = numberField2(cost, "deeplineUsdPerPricingUnit");
1941
- const displayText = stringField2(cost, "displayText");
1942
- const summary = stringField2(cost, "summary");
2318
+ const displayText = stringField(cost, "displayText");
2319
+ const summary = stringField(cost, "summary");
1943
2320
  const price = displayText || summary || (credits !== null ? `${formatDecimal(credits)} Deepline credits${usd !== null ? ` / ${formatUsd(usd)}` : ""} per ${unit}` : "pricing unavailable");
1944
2321
  return [
1945
2322
  `${options.heading ?? `Pricing: ${toolId}`}: ${price}`,
@@ -1961,7 +2338,12 @@ function printToolSchemaOnly(tool, requestedToolId) {
1961
2338
  printMonitorTypeStreams(tool);
1962
2339
  return;
1963
2340
  }
1964
- const contract = toolContractJsonForDescribe(tool, requestedToolId);
2341
+ const contract = toolContractJsonForDescribe(
2342
+ tool,
2343
+ requestedToolId,
2344
+ void 0,
2345
+ seedToolListScript
2346
+ );
1965
2347
  const inputFields = recursiveToolInputFieldsForDisplay(
1966
2348
  recordField(contract, "inputSchema")
1967
2349
  );
@@ -2010,10 +2392,15 @@ function printToolExamplesOnly(tool, requestedToolId) {
2010
2392
  printPlayLikeToolUsage(tool, requestedToolId);
2011
2393
  return;
2012
2394
  }
2013
- const contract = toolContractJsonForDescribe(tool, requestedToolId);
2395
+ const contract = toolContractJsonForDescribe(
2396
+ tool,
2397
+ requestedToolId,
2398
+ void 0,
2399
+ seedToolListScript
2400
+ );
2014
2401
  const toolId = String(contract.toolId);
2015
2402
  const inputFields = Array.isArray(contract.inputFields) ? contract.inputFields : [];
2016
- const examples = arrayField2(tool, "examples").filter(isRecord);
2403
+ const examples = arrayField(tool, "examples").filter(isRecord);
2017
2404
  const firstExample = examples[0];
2018
2405
  const sampleInput = firstExample && isRecord(firstExample.input) ? firstExample.input : samplePayload(recordField(tool, "samples"), "request") ?? samplePayloadForInputFields(inputFields);
2019
2406
  console.log("Example input payload:");
@@ -2034,8 +2421,8 @@ function printToolExamplesOnly(tool, requestedToolId) {
2034
2421
  const listGetters = Array.isArray(getters.extractedLists) ? getters.extractedLists : [];
2035
2422
  const firstGetter = valueGetters.find(isRecord);
2036
2423
  if (firstGetter) {
2037
- const name = stringField2(firstGetter, "name") || "value";
2038
- const expression = stringField2(firstGetter, "expression");
2424
+ const name = stringField(firstGetter, "name") || "value";
2425
+ const expression = stringField(firstGetter, "expression");
2039
2426
  if (expression)
2040
2427
  console.log(
2041
2428
  `const ${safeIdentifier(name)} = ${expression.replace(/^toolExecutionResult\./, "result.")};`
@@ -2047,10 +2434,10 @@ function printToolExamplesOnly(tool, requestedToolId) {
2047
2434
  ).filter((field) => String(field.type).split("|").includes("array")).map((field) => String(field.name).split(".").at(-1))
2048
2435
  );
2049
2436
  const firstList = listGetters.find(
2050
- (entry) => isRecord(entry) && arrayNames.has(stringField2(entry, "name"))
2437
+ (entry) => isRecord(entry) && arrayNames.has(stringField(entry, "name"))
2051
2438
  ) ?? listGetters.find(isRecord);
2052
2439
  if (isRecord(firstList)) {
2053
- const name = safeIdentifier(stringField2(firstList, "name") || "list");
2440
+ const name = safeIdentifier(stringField(firstList, "name") || "list");
2054
2441
  if (playToolListGetterMode() === "array") {
2055
2442
  console.log(`const ${name}_rows = ${playResultExpression(firstList)};`);
2056
2443
  } else {
@@ -2064,7 +2451,7 @@ function printToolExamplesOnly(tool, requestedToolId) {
2064
2451
  console.log("```");
2065
2452
  if (firstList) printListGetterConsumption();
2066
2453
  for (const example of examples) {
2067
- const description = stringField2(example, "description");
2454
+ const description = stringField(example, "description");
2068
2455
  if (description) console.log(description);
2069
2456
  console.log("Example Deepline execution response:");
2070
2457
  console.log(JSON.stringify(example.response, null, 2));
@@ -2097,7 +2484,12 @@ function printPlayLikeToolUsage(tool, requestedToolId) {
2097
2484
  }
2098
2485
  }
2099
2486
  function printToolGettersOnly(tool, requestedToolId) {
2100
- const contract = toolContractJsonForDescribe(tool, requestedToolId);
2487
+ const contract = toolContractJsonForDescribe(
2488
+ tool,
2489
+ requestedToolId,
2490
+ void 0,
2491
+ seedToolListScript
2492
+ );
2101
2493
  const getters = isRecord(contract.getters) ? contract.getters : {};
2102
2494
  const listGetters = Array.isArray(getters.extractedLists) ? getters.extractedLists : [];
2103
2495
  const valueGetters = Array.isArray(getters.extractedValues) ? getters.extractedValues : [];
@@ -2106,192 +2498,46 @@ function printToolGettersOnly(tool, requestedToolId) {
2106
2498
  console.log("No generated getters declared.");
2107
2499
  return;
2108
2500
  }
2109
- if (listGetters.length) {
2110
- console.log(listGetterHeading());
2111
- for (const entry of listGetters) {
2112
- if (isRecord(entry))
2113
- console.log(
2114
- `- ${stringField2(entry, "name")}: ${playResultExpression(entry)}`
2115
- );
2116
- }
2117
- printListGetterConsumption();
2118
- }
2119
- if (valueGetters.length) {
2120
- console.log("Values:");
2121
- for (const entry of valueGetters) {
2122
- if (isRecord(entry))
2123
- console.log(
2124
- `- ${stringField2(entry, "name")}: ${playResultExpression(entry)}`
2125
- );
2126
- }
2127
- }
2128
- }
2129
- function printListGetterConsumption() {
2130
- if (playToolListGetterMode() === "array") {
2131
- console.log(
2132
- "Use the ordinary array directly, or pass it to ctx.dataset to persist row work. No provider pagination is fetched. Lazy or incomplete lists throw; use readList for an explicit dataset read. A missing getter is not an empty list."
2133
- );
2134
- return;
2135
- }
2136
- console.log(
2137
- "Pass the handle to ctx.dataset, use first() for one row, or for await...of to stream rows. materialize() loads the complete current list within the memory cap; materialize(n) and peek(n) return only a prefix. None fetch additional provider pagination. A missing getter is not an empty list."
2138
- );
2139
- }
2140
- function listGetterHeading() {
2141
- return playToolListGetterMode() === "array" ? "Lists (ordinary JavaScript arrays):" : "Lists (PlayDataset, not a JavaScript array):";
2142
- }
2143
- function sampleValueForField(field) {
2144
- const name = stringField2(field, "name").toLowerCase();
2145
- const type = stringField2(field, "type").toLowerCase();
2146
- if (Object.prototype.hasOwnProperty.call(field, "default"))
2147
- return field.default;
2148
- if (name.includes("email")) return "ada@example.com";
2149
- if (name.includes("domain") || name.includes("website")) return "example.com";
2150
- if (name.includes("first")) return "Ada";
2151
- if (name.includes("last")) return "Lovelace";
2152
- if (name.includes("name")) return "Ada Lovelace";
2153
- if (type === "integer" || type === "number") return 1;
2154
- if (type === "boolean") return true;
2155
- if (type === "array") return [];
2156
- if (type === "object") return {};
2157
- return "...";
2158
- }
2159
- function samplePayloadForInputFields(fields) {
2160
- return Object.fromEntries(
2161
- fields.slice(0, 4).flatMap((field) => {
2162
- if (!isRecord(field)) return [];
2163
- const name = stringField2(field, "name");
2164
- if (!name) return [];
2165
- return [[name, sampleValueForField(field)]];
2166
- })
2167
- );
2168
- }
2169
- function stableStepIdForTool(toolId) {
2170
- return toolId.replace(/^[a-z0-9]+_/, "").replace(/[^a-z0-9_]+/gi, "_") || "tool_call";
2171
- }
2172
- function safeIdentifier(name) {
2173
- const cleaned = name.replace(/[^a-zA-Z0-9_$]+/g, "_").replace(/^[^a-zA-Z_$]+/, "");
2174
- return cleaned || "value";
2175
- }
2176
- function playResultExpression(entry) {
2177
- return stringField2(entry, "expression").replace(
2178
- /^toolExecutionResult\./,
2179
- "result."
2180
- );
2181
- }
2182
- function toolMetadataJsonForDescribe(tool, requestedToolId) {
2183
- const toolId = String(tool.toolId || requestedToolId);
2184
- const inputFields = toolInputFieldsForDisplay(
2185
- recordField(tool, "inputSchema", "input_schema")
2186
- );
2187
- const usageGuidance = usageGuidanceWithAccessDefaults(
2188
- recordField(tool, "usageGuidance", "usage_guidance")
2189
- );
2190
- const toolExecutionResult = recordField(
2191
- usageGuidance,
2192
- "toolExecutionResult",
2193
- "tool_execution_result"
2194
- );
2195
- const extractedLists = extractionContractEntries(
2196
- arrayField2(toolExecutionResult, "extractedLists", "extracted_lists")
2197
- );
2198
- const starterScript = !isPlayLikeTool(tool) && extractedLists.length > 0 ? starterScriptJson(
2199
- seedToolListScript({
2200
- toolId,
2201
- payload: samplePayloadForInputFields(inputFields),
2202
- rows: []
2203
- })
2204
- ) : null;
2205
- const observedOutputCommand = isPlayLikeTool(tool) ? playRunCommandForTool(tool, toolId) : `deepline tools execute ${toolId} --input '{...}'`;
2206
- const {
2207
- cost: _cost,
2208
- deeplineCreditsPerPricingUnit: _deeplineCreditsPerPricingUnit,
2209
- deeplineUsdPerPricingUnit: _deeplineUsdPerPricingUnit,
2210
- deeplineUsdPerCredit: _deeplineUsdPerCredit,
2211
- deeplinePricingSummary: _deeplinePricingSummary,
2212
- deeplinePricingDetails: _deeplinePricingDetails,
2213
- deepline_credits_per_pricing_unit: _snakeDeeplineCreditsPerPricingUnit,
2214
- deepline_usd_per_pricing_unit: _snakeDeeplineUsdPerPricingUnit,
2215
- deepline_usd_per_credit: _snakeDeeplineUsdPerCredit,
2216
- deepline_pricing_summary: _snakeDeeplinePricingSummary,
2217
- deepline_pricing_details: _snakeDeeplinePricingDetails,
2218
- // BYOK is shown only on request, via describe --feature byok.
2219
- byok: _byok,
2220
- ...publicTool
2221
- } = tool;
2222
- const outputSchemaRecord = recordField(tool, "outputSchema", "output_schema");
2223
- return {
2224
- cost: Capability.fromCatalogEntry(tool).describe().customerCost(),
2225
- ...publicTool,
2226
- toolId,
2227
- provider: tool.provider,
2228
- displayName: tool.displayName,
2229
- ...Object.keys(outputSchemaRecord).length > 0 ? {
2230
- outputSchema: publicToolInputSchemaForDescribe(outputSchemaRecord),
2231
- outputFields: toolOutputFieldsForDisplay(outputSchemaRecord).map(
2232
- inputFieldJsonForDescribe
2233
- )
2234
- } : {},
2235
- inputFields: inputFields.map(inputFieldJsonForDescribe),
2236
- usageGuidance,
2237
- runtimeOutputHelp: {
2238
- contract: "Schemas declare field shapes. Examples illustrate input payloads and full Deepline execution responses; they are not observed responses from this call.",
2239
- getterScope: "extractedValues/extractedLists .get() only works for declared Deepline getters listed in usageGuidance.toolExecutionResult.",
2240
- 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.",
2241
- invalidGetterHint: "If TypeScript says an extractedValues/extractedLists property does not exist, that field is not a declared Deepline getter.",
2242
- observeActualShape: observedOutputCommand,
2243
- observedOutput: observedOutputCommand,
2244
- forPlayGetterBugs: "Run a tiny play, inspect returned handles with `deepline runs get <run-id> --full`, then export row datasets with `deepline runs export`.",
2245
- executeOutputFields: "tools execute JSON may include output_preview for this direct probe only; play debugging uses run output and returned dataset handles."
2246
- },
2247
- ...starterScript ? { starterScript } : {}
2248
- };
2249
- }
2250
- function usageGuidanceWithAccessDefaults(usageGuidance) {
2251
- if (Object.keys(usageGuidance).length === 0) return usageGuidance;
2252
- const existingAccess = recordField(usageGuidance, "access");
2253
- return {
2254
- ...usageGuidance,
2255
- prefer: [
2256
- "Use only the declared extractedLists and extractedValues getters listed below.",
2257
- "Use toolExecutionResult.toolResponse.rawV2 for the complete tool response, preserving the nesting shown in the response example.",
2258
- "Schemas declare field shapes; examples illustrate input values and full Deepline execution responses."
2259
- ],
2260
- toolExecutionResult: {
2261
- ...recordField(
2262
- usageGuidance,
2263
- "toolExecutionResult",
2264
- "tool_execution_result"
2265
- ),
2266
- toolResponse: {
2267
- rawV2: "toolResponse.rawV2",
2268
- view: "toolResponse.view",
2269
- responseMeta: "toolResponse.responseMeta"
2270
- }
2271
- },
2272
- access: {
2273
- ...existingAccess,
2274
- extractedValues: {
2275
- expression: "toolExecutionResult.extractedValues.<name>.get()",
2276
- meaning: "Declared Deepline scalar or normalized object extractors only."
2277
- },
2278
- ...existingAccess,
2279
- extractedLists: {
2280
- ...recordField(existingAccess, "extractedLists"),
2281
- expression: "toolExecutionResult.extractedLists.<name>.get()",
2282
- meaning: playToolListGetterMode() === "array" ? "Returns an ordinary array from this response. Use array methods directly or pass it to ctx.dataset to persist row work. Lazy or incomplete lists throw; use readList for an explicit dataset read. It does not fetch provider pages." : "Returns a PlayDataset, not a JavaScript array. Pass the handle to ctx.dataset, use first(), async iteration, or await handle.materialize() for the complete current list within the memory cap. materialize(n) and peek(n) return a prefix; none fetch additional provider pages. A missing getter is not an empty list."
2283
- },
2284
- rawToolResponse: {
2285
- expression: "toolExecutionResult.toolResponse.rawV2",
2286
- meaning: "Complete tool response with its original nesting. Read tool-specific fields here; use declared getters for extracted values and lists."
2287
- },
2288
- canonicalToolResponse: {
2289
- expression: "toolExecutionResult.toolResponse.rawV2",
2290
- meaning: "Complete tool response with its original nesting and sibling fields."
2291
- },
2292
- 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."
2501
+ if (listGetters.length) {
2502
+ console.log(listGetterHeading());
2503
+ for (const entry of listGetters) {
2504
+ if (isRecord(entry))
2505
+ console.log(
2506
+ `- ${stringField(entry, "name")}: ${playResultExpression(entry)}`
2507
+ );
2293
2508
  }
2294
- };
2509
+ printListGetterConsumption();
2510
+ }
2511
+ if (valueGetters.length) {
2512
+ console.log("Values:");
2513
+ for (const entry of valueGetters) {
2514
+ if (isRecord(entry))
2515
+ console.log(
2516
+ `- ${stringField(entry, "name")}: ${playResultExpression(entry)}`
2517
+ );
2518
+ }
2519
+ }
2520
+ }
2521
+ function printListGetterConsumption() {
2522
+ if (playToolListGetterMode() === "array") {
2523
+ console.log(
2524
+ "Use the ordinary array directly, or pass it to ctx.dataset to persist row work. No provider pagination is fetched. Lazy or incomplete lists throw; use readList for an explicit dataset read. A missing getter is not an empty list."
2525
+ );
2526
+ return;
2527
+ }
2528
+ console.log(
2529
+ "Pass the handle to ctx.dataset, use first() for one row, or for await...of to stream rows. materialize() loads the complete current list within the memory cap; materialize(n) and peek(n) return only a prefix. None fetch additional provider pagination. A missing getter is not an empty list."
2530
+ );
2531
+ }
2532
+ function listGetterHeading() {
2533
+ return playToolListGetterMode() === "array" ? "Lists (ordinary JavaScript arrays):" : "Lists (PlayDataset, not a JavaScript array):";
2534
+ }
2535
+ function stableStepIdForTool(toolId) {
2536
+ return toolId.replace(/^[a-z0-9]+_/, "").replace(/[^a-z0-9_]+/gi, "_") || "tool_call";
2537
+ }
2538
+ function safeIdentifier(name) {
2539
+ const cleaned = name.replace(/[^a-zA-Z0-9_$]+/g, "_").replace(/^[^a-zA-Z_$]+/, "");
2540
+ return cleaned || "value";
2295
2541
  }
2296
2542
  function singleLineText(value2, maxLength = 260) {
2297
2543
  if (typeof value2 !== "string") return "";
@@ -2305,62 +2551,13 @@ function listedToolDescription(tool) {
2305
2551
  }
2306
2552
  function formatListedToolCost(tool) {
2307
2553
  const record = tool;
2308
- if (stringField2(record, "billingSource", "billing_source") === "free") {
2554
+ if (stringField(record, "billingSource", "billing_source") === "free") {
2309
2555
  return "Cost: Free";
2310
2556
  }
2311
2557
  const pricing = recordField(record, "pricing");
2312
- const displayText = stringField2(pricing, "displayText", "display_text");
2558
+ const displayText = stringField(pricing, "displayText", "display_text");
2313
2559
  return displayText ? `Cost: ${displayText}` : "";
2314
2560
  }
2315
- function toolInputFieldsForDisplay(inputSchema) {
2316
- if (Array.isArray(inputSchema.fields)) {
2317
- const fields = inputSchema.fields.filter(isRecord);
2318
- if (!isRecord(inputSchema.jsonSchema)) return fields;
2319
- const jsonSchemaFields = new Map(
2320
- recursiveToolInputFieldsForDisplay({
2321
- jsonSchema: inputSchema.jsonSchema
2322
- }).flatMap(
2323
- (field) => typeof field.name === "string" ? [[field.name, field]] : []
2324
- )
2325
- );
2326
- return fields.map((field) => {
2327
- const jsonSchemaField = typeof field.name === "string" ? jsonSchemaFields.get(field.name) : void 0;
2328
- const minItems = typeof field.minItems === "number" ? field.minItems : jsonSchemaField?.minItems;
2329
- const maxItems = typeof field.maxItems === "number" ? field.maxItems : jsonSchemaField?.maxItems;
2330
- const items = isRecord(field.items) ? field.items : jsonSchemaField?.items;
2331
- return {
2332
- ...field,
2333
- ...isRecord(items) ? { items } : {},
2334
- ...typeof minItems === "number" ? { minItems } : {},
2335
- ...typeof maxItems === "number" ? { maxItems } : {}
2336
- };
2337
- });
2338
- }
2339
- const jsonSchema = isRecord(inputSchema.jsonSchema) ? inputSchema.jsonSchema : inputSchema;
2340
- const properties = isRecord(jsonSchema.properties) ? jsonSchema.properties : {};
2341
- const required = Array.isArray(jsonSchema.required) ? new Set(jsonSchema.required.map(String)) : /* @__PURE__ */ new Set();
2342
- return Object.entries(properties).map(([name, value2]) => {
2343
- const property = isRecord(value2) ? value2 : {};
2344
- return {
2345
- name,
2346
- type: typeof property.type === "string" ? property.type : "unknown",
2347
- required: required.has(name),
2348
- description: property.description,
2349
- ...isRecord(property.items) ? { items: property.items } : {},
2350
- ...typeof property.minItems === "number" ? { minItems: property.minItems } : {},
2351
- ...typeof property.maxItems === "number" ? { maxItems: property.maxItems } : {},
2352
- ...Object.prototype.hasOwnProperty.call(property, "default") ? { default: property.default } : {}
2353
- };
2354
- });
2355
- }
2356
- function toolOutputFieldsForDisplay(outputSchema) {
2357
- if (Object.keys(outputSchema).length === 0) return [];
2358
- return recursiveToolInputFieldsForDisplay({
2359
- jsonSchema: outputSchema
2360
- }).filter(
2361
- (field) => typeof field.name === "string" && field.name.includes("[]")
2362
- );
2363
- }
2364
2561
  function printToolOutputArrayShape(tool) {
2365
2562
  const outputFields = toolOutputFieldsForDisplay(
2366
2563
  recordField(isRecord(tool) ? tool : {}, "outputSchema", "output_schema")
@@ -2369,7 +2566,7 @@ function printToolOutputArrayShape(tool) {
2369
2566
  console.log(" Output array shape (declared schema):");
2370
2567
  for (const field of outputFields.slice(0, 60)) {
2371
2568
  const name = String(field.name);
2372
- const type = stringField2(field, "type") || "unknown";
2569
+ const type = stringField(field, "type") || "unknown";
2373
2570
  const itemBounds = arrayItemBoundsSuffix(field);
2374
2571
  console.log(` - ${name}: ${type}${itemBounds}`);
2375
2572
  }
@@ -2377,142 +2574,12 @@ function printToolOutputArrayShape(tool) {
2377
2574
  console.log(` - \u2026 ${outputFields.length - 60} more schema fields`);
2378
2575
  }
2379
2576
  }
2380
- function canonicalToolJsonSchema(inputSchema) {
2381
- return isRecord(inputSchema.jsonSchema) ? inputSchema.jsonSchema : inputSchema;
2382
- }
2383
2577
  function declaredToolJsonSchema(inputSchema) {
2384
2578
  if (isRecord(inputSchema.jsonSchema)) {
2385
2579
  return inputSchema.jsonSchema;
2386
2580
  }
2387
2581
  return Array.isArray(inputSchema.fields) ? null : inputSchema;
2388
2582
  }
2389
- function publicToolInputSchemaForDescribe(inputSchema) {
2390
- const exposesProviderSpend = (description) => {
2391
- const withoutDeeplineCredits = description.replace(
2392
- /\bdeepline(?:-facing)?\s+credits?\b/gi,
2393
- ""
2394
- );
2395
- return /\bcredits?\b/i.test(withoutDeeplineCredits) || /\bprovider\s+(?:cost|spend|price|pricing|usage)\b/i.test(
2396
- withoutDeeplineCredits
2397
- ) || /\b(?:costs?|charges?|priced at)\s+[$€£]\s*\d/i.test(
2398
- withoutDeeplineCredits
2399
- ) || /\b(?:costs?|charges?|priced at)\s+\d+(?:\.\d+)?\s*(?:usd|eur|gbp)\b/i.test(
2400
- withoutDeeplineCredits
2401
- ) || /\battribute-priced\b/i.test(withoutDeeplineCredits) || /\b(?:cost|price|pricing)\s+(?:grows?|increases?|scales?|varies?)\b/i.test(
2402
- withoutDeeplineCredits
2403
- ) || /\b(?:will be|are|is|be)\s+(?:billed|charged)\b/i.test(
2404
- withoutDeeplineCredits
2405
- ) || /\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);
2406
- };
2407
- const stripDescriptions = (value2) => {
2408
- if (Array.isArray(value2)) return value2.map(stripDescriptions);
2409
- if (!isRecord(value2)) return value2;
2410
- return Object.fromEntries(
2411
- Object.entries(value2).flatMap(([key, nested]) => {
2412
- if (key === "description" && typeof nested === "string" && exposesProviderSpend(nested)) {
2413
- return [];
2414
- }
2415
- return [[key, stripDescriptions(nested)]];
2416
- })
2417
- );
2418
- };
2419
- return stripDescriptions(inputSchema);
2420
- }
2421
- function recursiveToolInputFieldsForDisplay(inputSchema) {
2422
- const root = canonicalToolJsonSchema(inputSchema);
2423
- const fields = /* @__PURE__ */ new Map();
2424
- const schemasById = /* @__PURE__ */ new Map();
2425
- const collectSchemaIds = (value2) => {
2426
- if (Array.isArray(value2)) {
2427
- for (const item of value2) collectSchemaIds(item);
2428
- return;
2429
- }
2430
- if (!isRecord(value2)) return;
2431
- if (typeof value2.$id === "string" && value2.$id.trim()) {
2432
- schemasById.set(value2.$id.trim(), value2);
2433
- }
2434
- for (const nested of Object.values(value2)) collectSchemaIds(nested);
2435
- };
2436
- collectSchemaIds(root);
2437
- const resolveRef = (schema) => {
2438
- const ref = typeof schema.$ref === "string" ? schema.$ref : "";
2439
- if (!ref.startsWith("#/")) return schemasById.get(ref) ?? schema;
2440
- let current = root;
2441
- for (const rawSegment of ref.slice(2).split("/")) {
2442
- const segment = rawSegment.replace(/~1/g, "/").replace(/~0/g, "~");
2443
- if (!isRecord(current)) return schema;
2444
- current = current[segment];
2445
- }
2446
- return isRecord(current) ? current : schema;
2447
- };
2448
- const addField = (field) => {
2449
- const name = typeof field.name === "string" ? field.name : "";
2450
- if (!name) return;
2451
- const existing = fields.get(name);
2452
- if (!existing || existing.type === "unknown") {
2453
- fields.set(name, field);
2454
- }
2455
- };
2456
- const visit = (unresolvedSchema, path, required, activeRefs = /* @__PURE__ */ new Set()) => {
2457
- const ref = typeof unresolvedSchema.$ref === "string" ? unresolvedSchema.$ref : "";
2458
- if (ref && activeRefs.has(ref)) return;
2459
- const schema = resolveRef(unresolvedSchema);
2460
- const nextActiveRefs = ref ? /* @__PURE__ */ new Set([...activeRefs, ref]) : activeRefs;
2461
- 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";
2462
- if (path) {
2463
- addField({
2464
- name: path,
2465
- type,
2466
- required,
2467
- description: schema.description,
2468
- ...Array.isArray(schema.enum) ? { enum: schema.enum } : {},
2469
- ...isRecord(schema.items) ? { items: schema.items } : {},
2470
- ...typeof schema.minItems === "number" ? { minItems: schema.minItems } : {},
2471
- ...typeof schema.maxItems === "number" ? { maxItems: schema.maxItems } : {},
2472
- ...Object.prototype.hasOwnProperty.call(schema, "default") ? { default: schema.default } : {}
2473
- });
2474
- }
2475
- const properties = isRecord(schema.properties) ? schema.properties : {};
2476
- const requiredNames = new Set(
2477
- Array.isArray(schema.required) ? schema.required.map(String) : []
2478
- );
2479
- for (const [name, value2] of Object.entries(properties)) {
2480
- if (!isRecord(value2)) continue;
2481
- visit(
2482
- value2,
2483
- path ? `${path}.${name}` : name,
2484
- requiredNames.has(name),
2485
- nextActiveRefs
2486
- );
2487
- }
2488
- if (isRecord(schema.items)) {
2489
- visit(schema.items, `${path}[]`, false, nextActiveRefs);
2490
- }
2491
- for (const keyword of ["anyOf", "oneOf", "allOf"]) {
2492
- const branches = Array.isArray(schema[keyword]) ? schema[keyword] : [];
2493
- for (const branch of branches) {
2494
- if (isRecord(branch)) {
2495
- visit(branch, path, required, nextActiveRefs);
2496
- }
2497
- }
2498
- }
2499
- };
2500
- visit(root, "", false);
2501
- return fields.size ? [...fields.values()] : toolInputFieldsForDisplay(inputSchema);
2502
- }
2503
- function inputFieldJsonForDescribe(field) {
2504
- const publicItems = isRecord(field.items) ? publicToolInputSchemaForDescribe({ items: field.items }).items : void 0;
2505
- return {
2506
- name: field.name,
2507
- type: field.type ?? "unknown",
2508
- required: Boolean(field.required),
2509
- ...field.description ? { description: field.description } : {},
2510
- ...isRecord(publicItems) ? { items: publicItems } : {},
2511
- ...typeof field.minItems === "number" ? { minItems: field.minItems } : {},
2512
- ...typeof field.maxItems === "number" ? { maxItems: field.maxItems } : {},
2513
- ...Object.prototype.hasOwnProperty.call(field, "default") ? { default: field.default } : {}
2514
- };
2515
- }
2516
2583
  function arrayItemBoundsSuffix(field) {
2517
2584
  const itemSchema = isRecord(field.items) ? field.items : null;
2518
2585
  const itemType = itemSchema ? typeof itemSchema.type === "string" ? itemSchema.type : isRecord(itemSchema.properties) ? "object" : "unknown" : null;
@@ -2540,9 +2607,9 @@ function printToolExecutionHints(value2) {
2540
2607
  "execution_metadata"
2541
2608
  );
2542
2609
  if (batchCapability) {
2543
- const status = stringField2(batchCapability, "status") || "unknown";
2544
- const surface = stringField2(batchCapability, "surface");
2545
- const operation = stringField2(
2610
+ const status = stringField(batchCapability, "status") || "unknown";
2611
+ const surface = stringField(batchCapability, "surface");
2612
+ const operation = stringField(
2546
2613
  batchCapability,
2547
2614
  "batchOperation",
2548
2615
  "batch_operation"
@@ -2552,7 +2619,7 @@ function printToolExecutionHints(value2) {
2552
2619
  "maxBatchSize",
2553
2620
  "max_batch_size"
2554
2621
  );
2555
- const notes = stringField2(batchCapability, "notes");
2622
+ const notes = stringField(batchCapability, "notes");
2556
2623
  console.log("");
2557
2624
  console.log("Batching:");
2558
2625
  console.log(`- Catalog status: ${status}${surface ? ` (${surface})` : ""}`);
@@ -2571,7 +2638,7 @@ function printToolExecutionHints(value2) {
2571
2638
  }
2572
2639
  if (notes) console.log(`- Details: ${notes}`);
2573
2640
  }
2574
- const configuredRateLimits = arrayField2(
2641
+ const configuredRateLimits = arrayField(
2575
2642
  executionMetadata,
2576
2643
  "configuredRateLimits",
2577
2644
  "configured_rate_limits"
@@ -2585,7 +2652,7 @@ function printToolExecutionHints(value2) {
2585
2652
  const requests = numberField2(limit, "requestsPerWindow");
2586
2653
  const windowMs = numberField2(limit, "windowMs");
2587
2654
  if (requests === null || windowMs === null) continue;
2588
- const usage = stringField2(limit, "usage") || "unknown";
2655
+ const usage = stringField(limit, "usage") || "unknown";
2589
2656
  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;
2590
2657
  const explicitMaxConcurrency = numberField2(
2591
2658
  limit,
@@ -2651,7 +2718,7 @@ function extractToolExecutionWarningMessages(rawResponse) {
2651
2718
  if (typeof warning === "string" && warning.trim()) {
2652
2719
  messages.push(warning.trim());
2653
2720
  } else if (isRecord(warning)) {
2654
- const message = stringField2(warning, "message");
2721
+ const message = stringField(warning, "message");
2655
2722
  if (message) messages.push(message);
2656
2723
  }
2657
2724
  }
@@ -2665,13 +2732,13 @@ function apifySyncRecoveryNext(rawResponse) {
2665
2732
  if (raw.state !== "awaiting_apify") return null;
2666
2733
  const next = recordField(raw, "next");
2667
2734
  const getActorRun = recordField(next, "getActorRun");
2668
- const getActorRunTool = stringField2(getActorRun, "tool");
2735
+ const getActorRunTool = stringField(getActorRun, "tool");
2669
2736
  const getActorRunPayload = recordField(getActorRun, "payload");
2670
2737
  if (!getActorRunTool || Object.keys(getActorRunPayload).length === 0) {
2671
2738
  return null;
2672
2739
  }
2673
2740
  const getDatasetItems = recordField(next, "getDatasetItems");
2674
- const getDatasetItemsTool = stringField2(getDatasetItems, "tool");
2741
+ const getDatasetItemsTool = stringField(getDatasetItems, "tool");
2675
2742
  const getDatasetItemsPayload = recordField(getDatasetItems, "payload");
2676
2743
  return {
2677
2744
  getActorRun: `deepline tools execute ${getActorRunTool} --input ${shellQuote(JSON.stringify(getActorRunPayload))}`,
@@ -2698,16 +2765,6 @@ function formatDecimal(value2) {
2698
2765
  function formatUsd(value2) {
2699
2766
  return `$${formatDecimal(value2)}`;
2700
2767
  }
2701
- function isRecord(value2) {
2702
- return Boolean(value2 && typeof value2 === "object" && !Array.isArray(value2));
2703
- }
2704
- function stringField2(source, ...keys) {
2705
- for (const key of keys) {
2706
- const value2 = source[key];
2707
- if (typeof value2 === "string" && value2.trim()) return value2.trim();
2708
- }
2709
- return "";
2710
- }
2711
2768
  function numberField2(source, ...keys) {
2712
2769
  for (const key of keys) {
2713
2770
  const value2 = source[key];
@@ -2715,20 +2772,6 @@ function numberField2(source, ...keys) {
2715
2772
  }
2716
2773
  return null;
2717
2774
  }
2718
- function arrayField2(source, ...keys) {
2719
- for (const key of keys) {
2720
- const value2 = source[key];
2721
- if (Array.isArray(value2)) return value2;
2722
- }
2723
- return [];
2724
- }
2725
- function recordField(source, ...keys) {
2726
- for (const key of keys) {
2727
- const value2 = source[key];
2728
- if (isRecord(value2)) return value2;
2729
- }
2730
- return {};
2731
- }
2732
2775
  function normalizeOutputFormat(raw) {
2733
2776
  switch ((raw || "auto").trim().toLowerCase()) {
2734
2777
  case "auto":
@@ -2880,17 +2923,6 @@ function safeFileStem(value2) {
2880
2923
  function powerShellQuote(value2) {
2881
2924
  return `'${value2.replace(/'/g, "''")}'`;
2882
2925
  }
2883
- function starterScriptJson(script) {
2884
- return {
2885
- path: script.path,
2886
- sourceCode: script.sourceCode,
2887
- projectDir: script.projectDir,
2888
- copyToProject: {
2889
- macosLinux: script.macCopyCommand,
2890
- windowsPowerShell: script.windowsCopyCommand
2891
- }
2892
- };
2893
- }
2894
2926
  function seedToolListScript(input) {
2895
2927
  const stem = safeFileStem(input.toolId);
2896
2928
  const fileName = `${stem}-workflow-seed-${Date.now()}.play.ts`;
@@ -3397,15 +3429,14 @@ inspect: ${inspection.inspect}
3397
3429
  }
3398
3430
 
3399
3431
  export {
3432
+ publicToolSchemas,
3433
+ describedTool,
3434
+ toolMetadataJsonForDescribe,
3400
3435
  formatModelDescription,
3401
- isMonitorTypeTool,
3402
3436
  registerToolsCommands,
3403
- toolContractJsonForDescribe,
3404
3437
  printMonitorTypeContract,
3405
- publicToolSchemas,
3406
- describedTool,
3407
3438
  printCompactToolContract,
3408
- toolMetadataJsonForDescribe,
3409
3439
  extractToolExecutionWarningMessages,
3440
+ seedToolListScript,
3410
3441
  buildToolExecuteBaseEnvelope
3411
3442
  };