deepline 0.1.11 → 0.1.12

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 (34) hide show
  1. package/README.md +4 -4
  2. package/dist/cli/index.js +509 -353
  3. package/dist/cli/index.js.map +1 -1
  4. package/dist/cli/index.mjs +513 -358
  5. package/dist/cli/index.mjs.map +1 -1
  6. package/dist/index.d.mts +250 -307
  7. package/dist/index.d.ts +250 -307
  8. package/dist/index.js +174 -315
  9. package/dist/index.js.map +1 -1
  10. package/dist/index.mjs +174 -314
  11. package/dist/index.mjs.map +1 -1
  12. package/dist/repo/apps/play-runner-workers/src/coordinator-entry.ts +23 -13
  13. package/dist/repo/apps/play-runner-workers/src/entry.ts +581 -1220
  14. package/dist/repo/sdk/src/cli/commands/play.ts +381 -247
  15. package/dist/repo/sdk/src/cli/commands/tools.ts +1 -1
  16. package/dist/repo/sdk/src/cli/dataset-stats.ts +86 -12
  17. package/dist/repo/sdk/src/client.ts +54 -51
  18. package/dist/repo/sdk/src/index.ts +7 -16
  19. package/dist/repo/sdk/src/play.ts +122 -140
  20. package/dist/repo/sdk/src/plays/bundle-play-file.ts +6 -3
  21. package/dist/repo/sdk/src/tool-output.ts +0 -146
  22. package/dist/repo/sdk/src/types.ts +2 -0
  23. package/dist/repo/sdk/src/version.ts +1 -1
  24. package/dist/repo/sdk/src/worker-play-entry.ts +3 -0
  25. package/dist/repo/shared_libs/play-runtime/context.ts +510 -267
  26. package/dist/repo/shared_libs/play-runtime/csv-rename.ts +180 -0
  27. package/dist/repo/shared_libs/play-runtime/ctx-types.ts +13 -1
  28. package/dist/repo/shared_libs/play-runtime/tool-result.ts +139 -114
  29. package/dist/repo/shared_libs/plays/bundling/index.ts +68 -5
  30. package/dist/repo/shared_libs/plays/compiler-manifest.ts +1 -1
  31. package/dist/repo/shared_libs/plays/dataset.ts +1 -1
  32. package/dist/repo/shared_libs/plays/runtime-validation.ts +8 -28
  33. package/package.json +1 -1
  34. package/dist/repo/apps/play-runner-workers/src/runtime/tool-result.ts +0 -184
package/dist/index.js CHANGED
@@ -30,7 +30,6 @@ __export(src_exports, {
30
30
  RateLimitError: () => RateLimitError,
31
31
  SDK_API_CONTRACT: () => SDK_API_CONTRACT,
32
32
  SDK_VERSION: () => SDK_VERSION,
33
- createToolCallResult: () => createToolCallResult,
34
33
  defineInput: () => defineInput,
35
34
  definePlay: () => definePlay,
36
35
  defineWorkflow: () => defineWorkflow,
@@ -196,7 +195,7 @@ function resolveConfig(options) {
196
195
  }
197
196
 
198
197
  // src/version.ts
199
- var SDK_VERSION = "0.1.11";
198
+ var SDK_VERSION = "0.1.12";
200
199
  var SDK_API_CONTRACT = "2026-04-plays-v1";
201
200
 
202
201
  // ../shared_libs/play-runtime/coordinator-headers.ts
@@ -471,6 +470,9 @@ function sleep(ms) {
471
470
 
472
471
  // src/client.ts
473
472
  var TERMINAL_PLAY_STATUSES = /* @__PURE__ */ new Set(["completed", "failed", "cancelled"]);
473
+ function isRecord(value) {
474
+ return Boolean(value && typeof value === "object" && !Array.isArray(value));
475
+ }
474
476
  function normalizePlayStatus(raw) {
475
477
  const status = typeof raw.status === "string" ? raw.status : typeof raw.temporalStatus === "string" ? mapLegacyTemporalStatus(raw.temporalStatus) : "running";
476
478
  const runId = typeof raw.runId === "string" ? raw.runId : typeof raw.workflowId === "string" ? raw.workflowId : "";
@@ -523,12 +525,27 @@ var DeeplineClient = class {
523
525
  ).filter((field) => Boolean(field?.name)) : [];
524
526
  return fields.length > 0 ? { fields } : schema;
525
527
  }
526
- playRunCommand(name) {
527
- return `deepline plays run ${name} --input '{...}' --watch`;
528
+ schemaMetadata(schema, key) {
529
+ if (!isRecord(schema)) return null;
530
+ const value = schema[key];
531
+ return isRecord(value) ? value : null;
532
+ }
533
+ playRunCommand(play, options) {
534
+ const target = play.reference || play.name;
535
+ if (options?.csvInput) {
536
+ const inputField = typeof options.csvInput.inputField === "string" && options.csvInput.inputField.trim() ? options.csvInput.inputField.trim() : "csv";
537
+ return `deepline plays run ${target} --${inputField} leads.csv --watch`;
538
+ }
539
+ return `deepline plays run ${target} --input '{...}' --watch`;
528
540
  }
529
541
  summarizePlayListItem(play, options) {
530
542
  const aliases = play.aliases?.length ? play.aliases : [play.name];
531
- const runCommand = this.playRunCommand(play.name);
543
+ const csvInput = this.schemaMetadata(play.inputSchema, "csvInput");
544
+ const rowOutputSchema = this.schemaMetadata(
545
+ play.outputSchema,
546
+ "rowOutputSchema"
547
+ );
548
+ const runCommand = this.playRunCommand(play, { csvInput });
532
549
  return {
533
550
  name: play.name,
534
551
  ...play.reference ? { reference: play.reference } : {},
@@ -540,6 +557,8 @@ var DeeplineClient = class {
540
557
  aliases,
541
558
  inputSchema: options?.compact ? this.compactSchema(play.inputSchema) : play.inputSchema ?? null,
542
559
  outputSchema: options?.compact ? this.compactSchema(play.outputSchema) : play.outputSchema ?? null,
560
+ ...csvInput ? { csvInput } : {},
561
+ ...rowOutputSchema ? { rowOutputSchema } : {},
543
562
  runCommand,
544
563
  examples: [runCommand],
545
564
  currentPublishedVersion: play.currentPublishedVersion ?? null,
@@ -606,50 +625,14 @@ var DeeplineClient = class {
606
625
  );
607
626
  }
608
627
  /**
609
- * Execute a tool and return the extracted result.
610
- *
611
- * Sends the input payload to the tool and returns the `.result` field from the
612
- * response. For the full response envelope (including job_id, credits, etc.),
613
- * use {@link executeToolRaw}.
614
- *
615
- * @param toolId - Tool identifier (e.g. `"test_company_search"`)
616
- * @param input - Tool-specific input parameters
617
- * @returns The tool's output (shape varies by tool)
618
- * @throws {@link DeeplineError} if the tool execution fails
628
+ * Execute a tool and return the standard execution envelope.
619
629
  *
620
- * @example
621
- * ```typescript
622
- * const company = await client.executeTool('test_company_search', {
623
- * domain: 'stripe.com',
624
- * });
625
- * console.log(company); // { name: "Stripe", industry: "Financial Services", ... }
626
- * ```
630
+ * The `result.data` field contains the provider payload. `result.meta`
631
+ * contains provider/upstream metadata such as HTTP status or paging details.
632
+ * Top-level fields such as `status`, `job_id`, and `billing` describe the
633
+ * Deepline execution.
627
634
  */
628
635
  async executeTool(toolId, input) {
629
- const res = await this.http.post(
630
- `/api/v2/integrations/${encodeURIComponent(toolId)}/execute`,
631
- { payload: input }
632
- );
633
- return res.result ?? res;
634
- }
635
- /**
636
- * Execute a tool and return the full response envelope.
637
- *
638
- * Unlike {@link executeTool}, this returns the complete API response including
639
- * `job_id`, `status`, `credits`, and the raw `result` object.
640
- *
641
- * @param toolId - Tool identifier
642
- * @param input - Tool-specific input parameters
643
- * @returns Full response with job metadata and result
644
- *
645
- * @example
646
- * ```typescript
647
- * const raw = await client.executeToolRaw('test_company_search', { domain: 'stripe.com' });
648
- * console.log(`Job: ${raw.job_id}, Credits: ${raw.credits}`);
649
- * console.log(`Result:`, raw.result);
650
- * ```
651
- */
652
- async executeToolRaw(toolId, input) {
653
636
  return this.http.post(
654
637
  `/api/v2/integrations/${encodeURIComponent(toolId)}/execute`,
655
638
  { payload: input }
@@ -1271,258 +1254,6 @@ var DeeplineClient = class {
1271
1254
  }
1272
1255
  };
1273
1256
 
1274
- // src/tool-output.ts
1275
- var import_node_fs2 = require("fs");
1276
- var import_node_os2 = require("os");
1277
- var import_node_path2 = require("path");
1278
- function isPlainObject(value) {
1279
- return Boolean(value) && typeof value === "object" && !Array.isArray(value);
1280
- }
1281
- var EMAIL_PATTERN = /^[^\s@]+@[^\s@]+\.[^\s@]+$/;
1282
- var PHONE_KEY_PATTERN = /(^|[_-])(phone|mobile|cell|telephone|tel)([_-]|$)|phone|mobile|telephone/i;
1283
- function normalizeScalarString(value) {
1284
- if (typeof value === "string") {
1285
- const trimmed = value.trim();
1286
- return trimmed.length > 0 ? trimmed : null;
1287
- }
1288
- if (typeof value === "number" && Number.isFinite(value)) {
1289
- return String(value);
1290
- }
1291
- return null;
1292
- }
1293
- function looksLikeEmail(value) {
1294
- const candidate = normalizeScalarString(value);
1295
- if (!candidate || !EMAIL_PATTERN.test(candidate)) return null;
1296
- return candidate;
1297
- }
1298
- function looksLikePhone(value) {
1299
- const candidate = normalizeScalarString(value);
1300
- if (!candidate) return null;
1301
- const digits = candidate.replace(/\D/g, "");
1302
- if (digits.length < 7 || digits.length > 16) return null;
1303
- return candidate;
1304
- }
1305
- function findEmail(value, depth = 0) {
1306
- if (depth > 6) return null;
1307
- const direct = looksLikeEmail(value);
1308
- if (direct) return direct;
1309
- if (Array.isArray(value)) {
1310
- for (const entry of value) {
1311
- const nested = findEmail(entry, depth + 1);
1312
- if (nested) return nested;
1313
- }
1314
- return null;
1315
- }
1316
- if (!isPlainObject(value)) return null;
1317
- for (const [key, child] of Object.entries(value)) {
1318
- if (/email/i.test(key)) {
1319
- const keyed = looksLikeEmail(child);
1320
- if (keyed) return keyed;
1321
- }
1322
- }
1323
- for (const child of Object.values(value)) {
1324
- const nested = findEmail(child, depth + 1);
1325
- if (nested) return nested;
1326
- }
1327
- return null;
1328
- }
1329
- function findPhone(value, depth = 0) {
1330
- if (depth > 6) return null;
1331
- if (Array.isArray(value)) {
1332
- for (const entry of value) {
1333
- const nested = findPhone(entry, depth + 1);
1334
- if (nested) return nested;
1335
- }
1336
- return null;
1337
- }
1338
- if (!isPlainObject(value)) return null;
1339
- for (const [key, child] of Object.entries(value)) {
1340
- if (PHONE_KEY_PATTERN.test(key)) {
1341
- const keyed = looksLikePhone(child);
1342
- if (keyed) return keyed;
1343
- }
1344
- }
1345
- for (const child of Object.values(value)) {
1346
- const nested = findPhone(child, depth + 1);
1347
- if (nested) return nested;
1348
- }
1349
- return null;
1350
- }
1351
- function normalizeListExtractorPaths(paths) {
1352
- if (!Array.isArray(paths)) return [];
1353
- const seen = /* @__PURE__ */ new Set();
1354
- const normalized = [];
1355
- for (const rawPath of paths) {
1356
- if (typeof rawPath !== "string") continue;
1357
- const path = rawPath.trim();
1358
- if (!path) continue;
1359
- for (const candidate of [path, path.replace(/^result\./, "")]) {
1360
- if (!candidate || seen.has(candidate)) continue;
1361
- seen.add(candidate);
1362
- normalized.push(candidate);
1363
- }
1364
- }
1365
- return normalized;
1366
- }
1367
- var DeeplineToolCallResult = class {
1368
- constructor(value, options) {
1369
- this.value = value;
1370
- this.listExtractorPaths = normalizeListExtractorPaths(
1371
- options?.listExtractorPaths
1372
- );
1373
- }
1374
- value;
1375
- listExtractorPaths;
1376
- getEmail() {
1377
- return findEmail(this.value);
1378
- }
1379
- getPhone() {
1380
- return findPhone(this.value);
1381
- }
1382
- tryList(options) {
1383
- const explicitPaths = normalizeListExtractorPaths(options?.listExtractorPaths);
1384
- return tryConvertToList(this.value, {
1385
- listExtractorPaths: explicitPaths.length > 0 ? explicitPaths : this.listExtractorPaths
1386
- })?.rows ?? null;
1387
- }
1388
- };
1389
- function createToolCallResult(value, options) {
1390
- return new DeeplineToolCallResult(value, options);
1391
- }
1392
- function getByDottedPath(root, dottedPath) {
1393
- let current = root;
1394
- for (const segment of String(dottedPath || "").split(".").filter(Boolean)) {
1395
- if (!isPlainObject(current) || !(segment in current)) {
1396
- return null;
1397
- }
1398
- current = current[segment];
1399
- }
1400
- return current;
1401
- }
1402
- function normalizeRows(value) {
1403
- if (!Array.isArray(value)) return null;
1404
- return value.map((entry) => {
1405
- if (isPlainObject(entry)) return entry;
1406
- return { value: entry };
1407
- });
1408
- }
1409
- function candidateRoots(payload) {
1410
- const roots = [{ path: null, value: payload }];
1411
- if (isPlainObject(payload) && isPlainObject(payload.result)) {
1412
- roots.push({ path: "result", value: payload.result });
1413
- if (isPlainObject(payload.result.data)) {
1414
- roots.push({ path: "result.data", value: payload.result.data });
1415
- }
1416
- }
1417
- return roots;
1418
- }
1419
- function findBestArrayCandidate(value, pathPrefix = "", depth = 0) {
1420
- if (depth > 5) return null;
1421
- const directRows = normalizeRows(value);
1422
- const hasObjectRow = directRows?.some((row) => Object.keys(row).some((key) => key !== "value")) ?? false;
1423
- let best = directRows && directRows.length > 0 && hasObjectRow ? { path: pathPrefix, rows: directRows } : null;
1424
- if (!isPlainObject(value)) {
1425
- return best;
1426
- }
1427
- for (const [key, child] of Object.entries(value)) {
1428
- const childPath = pathPrefix ? `${pathPrefix}.${key}` : key;
1429
- const candidate = findBestArrayCandidate(child, childPath, depth + 1);
1430
- if (!candidate) continue;
1431
- if (!best || candidate.rows.length > best.rows.length) {
1432
- best = candidate;
1433
- }
1434
- }
1435
- return best;
1436
- }
1437
- function tryConvertToList(payload, options) {
1438
- const listExtractorPaths = Array.isArray(options?.listExtractorPaths) ? options?.listExtractorPaths.filter((entry) => typeof entry === "string" && entry.trim().length > 0) : [];
1439
- if (listExtractorPaths.length > 0) {
1440
- for (const root of candidateRoots(payload)) {
1441
- for (const extractorPath of listExtractorPaths) {
1442
- const resolved = getByDottedPath(root.value, extractorPath);
1443
- const rows = normalizeRows(resolved);
1444
- if (rows && rows.length > 0) {
1445
- const sourcePath = root.path ? `${root.path}.${extractorPath}` : extractorPath;
1446
- return { rows, strategy: "configured_paths", sourcePath };
1447
- }
1448
- }
1449
- }
1450
- }
1451
- for (const root of candidateRoots(payload)) {
1452
- const candidate = findBestArrayCandidate(root.value, root.path ?? "");
1453
- if (!candidate || candidate.rows.length === 0) continue;
1454
- return {
1455
- rows: candidate.rows,
1456
- strategy: "auto_detected",
1457
- sourcePath: candidate.path || root.path
1458
- };
1459
- }
1460
- return null;
1461
- }
1462
- function ensureOutputDir() {
1463
- const outputDir = (0, import_node_path2.join)((0, import_node_os2.homedir)(), ".local", "share", "deepline", "data");
1464
- (0, import_node_fs2.mkdirSync)(outputDir, { recursive: true });
1465
- return outputDir;
1466
- }
1467
- function writeJsonOutputFile(payload, stem) {
1468
- const outputDir = ensureOutputDir();
1469
- const outputPath = (0, import_node_path2.join)(outputDir, `${stem}_${Date.now()}.json`);
1470
- (0, import_node_fs2.writeFileSync)(outputPath, JSON.stringify(payload, null, 2), "utf-8");
1471
- return outputPath;
1472
- }
1473
- function writeCsvOutputFile(rows, stem) {
1474
- const outputDir = ensureOutputDir();
1475
- const outputPath = (0, import_node_path2.join)(outputDir, `${stem}_${Date.now()}.csv`);
1476
- const seen = /* @__PURE__ */ new Set();
1477
- const columns = [];
1478
- for (const row of rows) {
1479
- for (const key of Object.keys(row)) {
1480
- if (!seen.has(key)) {
1481
- seen.add(key);
1482
- columns.push(key);
1483
- }
1484
- }
1485
- }
1486
- const escapeCell = (value) => {
1487
- const normalized = value == null ? "" : typeof value === "string" || typeof value === "number" || typeof value === "boolean" ? String(value) : JSON.stringify(value);
1488
- if (/[",\n]/.test(normalized)) {
1489
- return `"${normalized.replace(/"/g, '""')}"`;
1490
- }
1491
- return normalized;
1492
- };
1493
- const lines = [];
1494
- lines.push(columns.map(escapeCell).join(","));
1495
- for (const row of rows) {
1496
- lines.push(columns.map((column) => escapeCell(row[column])).join(","));
1497
- }
1498
- (0, import_node_fs2.writeFileSync)(outputPath, `${lines.join("\n")}
1499
- `, "utf-8");
1500
- const previewRows = rows.slice(0, 5);
1501
- const previewColumns = columns.slice(0, 5);
1502
- const preview = [
1503
- previewColumns.join(","),
1504
- ...previewRows.map((row) => previewColumns.map((column) => escapeCell(row[column])).join(","))
1505
- ].join("\n");
1506
- return {
1507
- path: outputPath,
1508
- rowCount: rows.length,
1509
- columns,
1510
- preview
1511
- };
1512
- }
1513
- function extractSummaryFields(payload) {
1514
- const candidates = candidateRoots(payload);
1515
- for (const candidate of candidates) {
1516
- if (!isPlainObject(candidate.value)) continue;
1517
- const summaryEntries = Object.entries(candidate.value).filter(([, value]) => {
1518
- return value == null || typeof value === "string" || typeof value === "number" || typeof value === "boolean";
1519
- });
1520
- if (summaryEntries.length === 0) continue;
1521
- return Object.fromEntries(summaryEntries);
1522
- }
1523
- return {};
1524
- }
1525
-
1526
1257
  // src/play.ts
1527
1258
  var DeeplineConditionalStepResolver = class _DeeplineConditionalStepResolver {
1528
1259
  constructor(when2, run, elseValue) {
@@ -1661,12 +1392,8 @@ var DeeplineContext = class {
1661
1392
  * ```typescript
1662
1393
  * const tools = await ctx.tools.list();
1663
1394
  * const meta = await ctx.tools.get('apollo_people_search');
1664
- * const result = await ctx.tools.execute({
1665
- * tool: 'test_company_search',
1666
- * input: { domain: 'stripe.com' },
1667
- * });
1668
- * const rows = result.tryList({ listExtractorPaths: ['people'] });
1669
- * const email = result.getEmail();
1395
+ * const companyLookup = await ctx.tools.execute('test_company_search', { domain: 'stripe.com' });
1396
+ * const company = companyLookup.result.data;
1670
1397
  * ```
1671
1398
  */
1672
1399
  get tools() {
@@ -1675,16 +1402,8 @@ var DeeplineContext = class {
1675
1402
  list: () => this.client.listTools(),
1676
1403
  /** Get detailed metadata for a tool. */
1677
1404
  get: (toolId) => this.client.getTool(toolId),
1678
- /** Execute a tool and return an ergonomic result wrapper. */
1679
- execute: async (request) => {
1680
- const [metadata, value] = await Promise.all([
1681
- this.client.getTool(request.tool),
1682
- this.client.executeTool(request.tool, request.input)
1683
- ]);
1684
- return createToolCallResult(value, {
1685
- listExtractorPaths: metadata.listExtractorPaths ?? []
1686
- });
1687
- }
1405
+ /** Execute a tool and return the standard execution envelope. */
1406
+ execute: async (toolId, input) => this.client.executeTool(toolId, input)
1688
1407
  };
1689
1408
  }
1690
1409
  get plays() {
@@ -1887,6 +1606,147 @@ function getDefinedPlayMetadata(value) {
1887
1606
  }
1888
1607
  return candidate;
1889
1608
  }
1609
+
1610
+ // src/tool-output.ts
1611
+ var import_node_fs2 = require("fs");
1612
+ var import_node_os2 = require("os");
1613
+ var import_node_path2 = require("path");
1614
+ function isPlainObject(value) {
1615
+ return Boolean(value) && typeof value === "object" && !Array.isArray(value);
1616
+ }
1617
+ function getByDottedPath(root, dottedPath) {
1618
+ let current = root;
1619
+ for (const segment of String(dottedPath || "").split(".").filter(Boolean)) {
1620
+ if (!isPlainObject(current) || !(segment in current)) {
1621
+ return null;
1622
+ }
1623
+ current = current[segment];
1624
+ }
1625
+ return current;
1626
+ }
1627
+ function normalizeRows(value) {
1628
+ if (!Array.isArray(value)) return null;
1629
+ return value.map((entry) => {
1630
+ if (isPlainObject(entry)) return entry;
1631
+ return { value: entry };
1632
+ });
1633
+ }
1634
+ function candidateRoots(payload) {
1635
+ const roots = [{ path: null, value: payload }];
1636
+ if (isPlainObject(payload) && isPlainObject(payload.result)) {
1637
+ roots.push({ path: "result", value: payload.result });
1638
+ if (isPlainObject(payload.result.data)) {
1639
+ roots.push({ path: "result.data", value: payload.result.data });
1640
+ }
1641
+ }
1642
+ return roots;
1643
+ }
1644
+ function findBestArrayCandidate(value, pathPrefix = "", depth = 0) {
1645
+ if (depth > 5) return null;
1646
+ const directRows = normalizeRows(value);
1647
+ const hasObjectRow = directRows?.some((row) => Object.keys(row).some((key) => key !== "value")) ?? false;
1648
+ let best = directRows && directRows.length > 0 && hasObjectRow ? { path: pathPrefix, rows: directRows } : null;
1649
+ if (!isPlainObject(value)) {
1650
+ return best;
1651
+ }
1652
+ for (const [key, child] of Object.entries(value)) {
1653
+ const childPath = pathPrefix ? `${pathPrefix}.${key}` : key;
1654
+ const candidate = findBestArrayCandidate(child, childPath, depth + 1);
1655
+ if (!candidate) continue;
1656
+ if (!best || candidate.rows.length > best.rows.length) {
1657
+ best = candidate;
1658
+ }
1659
+ }
1660
+ return best;
1661
+ }
1662
+ function tryConvertToList(payload, options) {
1663
+ const listExtractorPaths = Array.isArray(options?.listExtractorPaths) ? options?.listExtractorPaths.filter((entry) => typeof entry === "string" && entry.trim().length > 0) : [];
1664
+ if (listExtractorPaths.length > 0) {
1665
+ for (const root of candidateRoots(payload)) {
1666
+ for (const extractorPath of listExtractorPaths) {
1667
+ const resolved = getByDottedPath(root.value, extractorPath);
1668
+ const rows = normalizeRows(resolved);
1669
+ if (rows && rows.length > 0) {
1670
+ const sourcePath = root.path ? `${root.path}.${extractorPath}` : extractorPath;
1671
+ return { rows, strategy: "configured_paths", sourcePath };
1672
+ }
1673
+ }
1674
+ }
1675
+ }
1676
+ for (const root of candidateRoots(payload)) {
1677
+ const candidate = findBestArrayCandidate(root.value, root.path ?? "");
1678
+ if (!candidate || candidate.rows.length === 0) continue;
1679
+ return {
1680
+ rows: candidate.rows,
1681
+ strategy: "auto_detected",
1682
+ sourcePath: candidate.path || root.path
1683
+ };
1684
+ }
1685
+ return null;
1686
+ }
1687
+ function ensureOutputDir() {
1688
+ const outputDir = (0, import_node_path2.join)((0, import_node_os2.homedir)(), ".local", "share", "deepline", "data");
1689
+ (0, import_node_fs2.mkdirSync)(outputDir, { recursive: true });
1690
+ return outputDir;
1691
+ }
1692
+ function writeJsonOutputFile(payload, stem) {
1693
+ const outputDir = ensureOutputDir();
1694
+ const outputPath = (0, import_node_path2.join)(outputDir, `${stem}_${Date.now()}.json`);
1695
+ (0, import_node_fs2.writeFileSync)(outputPath, JSON.stringify(payload, null, 2), "utf-8");
1696
+ return outputPath;
1697
+ }
1698
+ function writeCsvOutputFile(rows, stem) {
1699
+ const outputDir = ensureOutputDir();
1700
+ const outputPath = (0, import_node_path2.join)(outputDir, `${stem}_${Date.now()}.csv`);
1701
+ const seen = /* @__PURE__ */ new Set();
1702
+ const columns = [];
1703
+ for (const row of rows) {
1704
+ for (const key of Object.keys(row)) {
1705
+ if (!seen.has(key)) {
1706
+ seen.add(key);
1707
+ columns.push(key);
1708
+ }
1709
+ }
1710
+ }
1711
+ const escapeCell = (value) => {
1712
+ const normalized = value == null ? "" : typeof value === "string" || typeof value === "number" || typeof value === "boolean" ? String(value) : JSON.stringify(value);
1713
+ if (/[",\n]/.test(normalized)) {
1714
+ return `"${normalized.replace(/"/g, '""')}"`;
1715
+ }
1716
+ return normalized;
1717
+ };
1718
+ const lines = [];
1719
+ lines.push(columns.map(escapeCell).join(","));
1720
+ for (const row of rows) {
1721
+ lines.push(columns.map((column) => escapeCell(row[column])).join(","));
1722
+ }
1723
+ (0, import_node_fs2.writeFileSync)(outputPath, `${lines.join("\n")}
1724
+ `, "utf-8");
1725
+ const previewRows = rows.slice(0, 5);
1726
+ const previewColumns = columns.slice(0, 5);
1727
+ const preview = [
1728
+ previewColumns.join(","),
1729
+ ...previewRows.map((row) => previewColumns.map((column) => escapeCell(row[column])).join(","))
1730
+ ].join("\n");
1731
+ return {
1732
+ path: outputPath,
1733
+ rowCount: rows.length,
1734
+ columns,
1735
+ preview
1736
+ };
1737
+ }
1738
+ function extractSummaryFields(payload) {
1739
+ const candidates = candidateRoots(payload);
1740
+ for (const candidate of candidates) {
1741
+ if (!isPlainObject(candidate.value)) continue;
1742
+ const summaryEntries = Object.entries(candidate.value).filter(([, value]) => {
1743
+ return value == null || typeof value === "string" || typeof value === "number" || typeof value === "boolean";
1744
+ });
1745
+ if (summaryEntries.length === 0) continue;
1746
+ return Object.fromEntries(summaryEntries);
1747
+ }
1748
+ return {};
1749
+ }
1890
1750
  // Annotate the CommonJS export names for ESM import in node:
1891
1751
  0 && (module.exports = {
1892
1752
  AuthError,
@@ -1899,7 +1759,6 @@ function getDefinedPlayMetadata(value) {
1899
1759
  RateLimitError,
1900
1760
  SDK_API_CONTRACT,
1901
1761
  SDK_VERSION,
1902
- createToolCallResult,
1903
1762
  defineInput,
1904
1763
  definePlay,
1905
1764
  defineWorkflow,