deepline 0.1.10 → 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.
- package/README.md +4 -4
- package/dist/cli/index.js +509 -353
- package/dist/cli/index.js.map +1 -1
- package/dist/cli/index.mjs +513 -358
- package/dist/cli/index.mjs.map +1 -1
- package/dist/index.d.mts +250 -305
- package/dist/index.d.ts +250 -305
- package/dist/index.js +174 -286
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +174 -285
- package/dist/index.mjs.map +1 -1
- package/dist/repo/apps/play-runner-workers/src/coordinator-entry.ts +23 -13
- package/dist/repo/apps/play-runner-workers/src/entry.ts +581 -1220
- package/dist/repo/sdk/src/cli/commands/play.ts +381 -247
- package/dist/repo/sdk/src/cli/commands/tools.ts +1 -1
- package/dist/repo/sdk/src/cli/dataset-stats.ts +86 -12
- package/dist/repo/sdk/src/client.ts +54 -51
- package/dist/repo/sdk/src/index.ts +7 -16
- package/dist/repo/sdk/src/play.ts +122 -135
- package/dist/repo/sdk/src/plays/bundle-play-file.ts +6 -3
- package/dist/repo/sdk/src/tool-output.ts +0 -111
- package/dist/repo/sdk/src/types.ts +2 -0
- package/dist/repo/sdk/src/version.ts +1 -1
- package/dist/repo/sdk/src/worker-play-entry.ts +3 -0
- package/dist/repo/shared_libs/play-runtime/context.ts +510 -267
- package/dist/repo/shared_libs/play-runtime/csv-rename.ts +180 -0
- package/dist/repo/shared_libs/play-runtime/ctx-types.ts +13 -1
- package/dist/repo/shared_libs/play-runtime/tool-result.ts +139 -114
- package/dist/repo/shared_libs/plays/bundling/index.ts +68 -5
- package/dist/repo/shared_libs/plays/compiler-manifest.ts +1 -1
- package/dist/repo/shared_libs/plays/dataset.ts +1 -1
- package/dist/repo/shared_libs/plays/runtime-validation.ts +8 -28
- package/package.json +1 -1
- 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.
|
|
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
|
-
|
|
527
|
-
|
|
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
|
|
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
|
|
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
|
-
*
|
|
621
|
-
*
|
|
622
|
-
*
|
|
623
|
-
*
|
|
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,235 +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
|
-
var DeeplineToolCallResult = class {
|
|
1352
|
-
constructor(value) {
|
|
1353
|
-
this.value = value;
|
|
1354
|
-
}
|
|
1355
|
-
value;
|
|
1356
|
-
getEmail() {
|
|
1357
|
-
return findEmail(this.value);
|
|
1358
|
-
}
|
|
1359
|
-
getPhone() {
|
|
1360
|
-
return findPhone(this.value);
|
|
1361
|
-
}
|
|
1362
|
-
tryList(options) {
|
|
1363
|
-
return tryConvertToList(this.value, options)?.rows ?? null;
|
|
1364
|
-
}
|
|
1365
|
-
};
|
|
1366
|
-
function createToolCallResult(value) {
|
|
1367
|
-
return new DeeplineToolCallResult(value);
|
|
1368
|
-
}
|
|
1369
|
-
function getByDottedPath(root, dottedPath) {
|
|
1370
|
-
let current = root;
|
|
1371
|
-
for (const segment of String(dottedPath || "").split(".").filter(Boolean)) {
|
|
1372
|
-
if (!isPlainObject(current) || !(segment in current)) {
|
|
1373
|
-
return null;
|
|
1374
|
-
}
|
|
1375
|
-
current = current[segment];
|
|
1376
|
-
}
|
|
1377
|
-
return current;
|
|
1378
|
-
}
|
|
1379
|
-
function normalizeRows(value) {
|
|
1380
|
-
if (!Array.isArray(value)) return null;
|
|
1381
|
-
return value.map((entry) => {
|
|
1382
|
-
if (isPlainObject(entry)) return entry;
|
|
1383
|
-
return { value: entry };
|
|
1384
|
-
});
|
|
1385
|
-
}
|
|
1386
|
-
function candidateRoots(payload) {
|
|
1387
|
-
const roots = [{ path: null, value: payload }];
|
|
1388
|
-
if (isPlainObject(payload) && isPlainObject(payload.result)) {
|
|
1389
|
-
roots.push({ path: "result", value: payload.result });
|
|
1390
|
-
if (isPlainObject(payload.result.data)) {
|
|
1391
|
-
roots.push({ path: "result.data", value: payload.result.data });
|
|
1392
|
-
}
|
|
1393
|
-
}
|
|
1394
|
-
return roots;
|
|
1395
|
-
}
|
|
1396
|
-
function findBestArrayCandidate(value, pathPrefix = "", depth = 0) {
|
|
1397
|
-
if (depth > 5) return null;
|
|
1398
|
-
const directRows = normalizeRows(value);
|
|
1399
|
-
const hasObjectRow = directRows?.some((row) => Object.keys(row).some((key) => key !== "value")) ?? false;
|
|
1400
|
-
let best = directRows && directRows.length > 0 && hasObjectRow ? { path: pathPrefix, rows: directRows } : null;
|
|
1401
|
-
if (!isPlainObject(value)) {
|
|
1402
|
-
return best;
|
|
1403
|
-
}
|
|
1404
|
-
for (const [key, child] of Object.entries(value)) {
|
|
1405
|
-
const childPath = pathPrefix ? `${pathPrefix}.${key}` : key;
|
|
1406
|
-
const candidate = findBestArrayCandidate(child, childPath, depth + 1);
|
|
1407
|
-
if (!candidate) continue;
|
|
1408
|
-
if (!best || candidate.rows.length > best.rows.length) {
|
|
1409
|
-
best = candidate;
|
|
1410
|
-
}
|
|
1411
|
-
}
|
|
1412
|
-
return best;
|
|
1413
|
-
}
|
|
1414
|
-
function tryConvertToList(payload, options) {
|
|
1415
|
-
const listExtractorPaths = Array.isArray(options?.listExtractorPaths) ? options?.listExtractorPaths.filter((entry) => typeof entry === "string" && entry.trim().length > 0) : [];
|
|
1416
|
-
if (listExtractorPaths.length > 0) {
|
|
1417
|
-
for (const root of candidateRoots(payload)) {
|
|
1418
|
-
for (const extractorPath of listExtractorPaths) {
|
|
1419
|
-
const resolved = getByDottedPath(root.value, extractorPath);
|
|
1420
|
-
const rows = normalizeRows(resolved);
|
|
1421
|
-
if (rows && rows.length > 0) {
|
|
1422
|
-
const sourcePath = root.path ? `${root.path}.${extractorPath}` : extractorPath;
|
|
1423
|
-
return { rows, strategy: "configured_paths", sourcePath };
|
|
1424
|
-
}
|
|
1425
|
-
}
|
|
1426
|
-
}
|
|
1427
|
-
}
|
|
1428
|
-
for (const root of candidateRoots(payload)) {
|
|
1429
|
-
const candidate = findBestArrayCandidate(root.value, root.path ?? "");
|
|
1430
|
-
if (!candidate || candidate.rows.length === 0) continue;
|
|
1431
|
-
return {
|
|
1432
|
-
rows: candidate.rows,
|
|
1433
|
-
strategy: "auto_detected",
|
|
1434
|
-
sourcePath: candidate.path || root.path
|
|
1435
|
-
};
|
|
1436
|
-
}
|
|
1437
|
-
return null;
|
|
1438
|
-
}
|
|
1439
|
-
function ensureOutputDir() {
|
|
1440
|
-
const outputDir = (0, import_node_path2.join)((0, import_node_os2.homedir)(), ".local", "share", "deepline", "data");
|
|
1441
|
-
(0, import_node_fs2.mkdirSync)(outputDir, { recursive: true });
|
|
1442
|
-
return outputDir;
|
|
1443
|
-
}
|
|
1444
|
-
function writeJsonOutputFile(payload, stem) {
|
|
1445
|
-
const outputDir = ensureOutputDir();
|
|
1446
|
-
const outputPath = (0, import_node_path2.join)(outputDir, `${stem}_${Date.now()}.json`);
|
|
1447
|
-
(0, import_node_fs2.writeFileSync)(outputPath, JSON.stringify(payload, null, 2), "utf-8");
|
|
1448
|
-
return outputPath;
|
|
1449
|
-
}
|
|
1450
|
-
function writeCsvOutputFile(rows, stem) {
|
|
1451
|
-
const outputDir = ensureOutputDir();
|
|
1452
|
-
const outputPath = (0, import_node_path2.join)(outputDir, `${stem}_${Date.now()}.csv`);
|
|
1453
|
-
const seen = /* @__PURE__ */ new Set();
|
|
1454
|
-
const columns = [];
|
|
1455
|
-
for (const row of rows) {
|
|
1456
|
-
for (const key of Object.keys(row)) {
|
|
1457
|
-
if (!seen.has(key)) {
|
|
1458
|
-
seen.add(key);
|
|
1459
|
-
columns.push(key);
|
|
1460
|
-
}
|
|
1461
|
-
}
|
|
1462
|
-
}
|
|
1463
|
-
const escapeCell = (value) => {
|
|
1464
|
-
const normalized = value == null ? "" : typeof value === "string" || typeof value === "number" || typeof value === "boolean" ? String(value) : JSON.stringify(value);
|
|
1465
|
-
if (/[",\n]/.test(normalized)) {
|
|
1466
|
-
return `"${normalized.replace(/"/g, '""')}"`;
|
|
1467
|
-
}
|
|
1468
|
-
return normalized;
|
|
1469
|
-
};
|
|
1470
|
-
const lines = [];
|
|
1471
|
-
lines.push(columns.map(escapeCell).join(","));
|
|
1472
|
-
for (const row of rows) {
|
|
1473
|
-
lines.push(columns.map((column) => escapeCell(row[column])).join(","));
|
|
1474
|
-
}
|
|
1475
|
-
(0, import_node_fs2.writeFileSync)(outputPath, `${lines.join("\n")}
|
|
1476
|
-
`, "utf-8");
|
|
1477
|
-
const previewRows = rows.slice(0, 5);
|
|
1478
|
-
const previewColumns = columns.slice(0, 5);
|
|
1479
|
-
const preview = [
|
|
1480
|
-
previewColumns.join(","),
|
|
1481
|
-
...previewRows.map((row) => previewColumns.map((column) => escapeCell(row[column])).join(","))
|
|
1482
|
-
].join("\n");
|
|
1483
|
-
return {
|
|
1484
|
-
path: outputPath,
|
|
1485
|
-
rowCount: rows.length,
|
|
1486
|
-
columns,
|
|
1487
|
-
preview
|
|
1488
|
-
};
|
|
1489
|
-
}
|
|
1490
|
-
function extractSummaryFields(payload) {
|
|
1491
|
-
const candidates = candidateRoots(payload);
|
|
1492
|
-
for (const candidate of candidates) {
|
|
1493
|
-
if (!isPlainObject(candidate.value)) continue;
|
|
1494
|
-
const summaryEntries = Object.entries(candidate.value).filter(([, value]) => {
|
|
1495
|
-
return value == null || typeof value === "string" || typeof value === "number" || typeof value === "boolean";
|
|
1496
|
-
});
|
|
1497
|
-
if (summaryEntries.length === 0) continue;
|
|
1498
|
-
return Object.fromEntries(summaryEntries);
|
|
1499
|
-
}
|
|
1500
|
-
return {};
|
|
1501
|
-
}
|
|
1502
|
-
|
|
1503
1257
|
// src/play.ts
|
|
1504
1258
|
var DeeplineConditionalStepResolver = class _DeeplineConditionalStepResolver {
|
|
1505
1259
|
constructor(when2, run, elseValue) {
|
|
@@ -1638,12 +1392,8 @@ var DeeplineContext = class {
|
|
|
1638
1392
|
* ```typescript
|
|
1639
1393
|
* const tools = await ctx.tools.list();
|
|
1640
1394
|
* const meta = await ctx.tools.get('apollo_people_search');
|
|
1641
|
-
* const
|
|
1642
|
-
*
|
|
1643
|
-
* input: { domain: 'stripe.com' },
|
|
1644
|
-
* });
|
|
1645
|
-
* const rows = result.tryList({ listExtractorPaths: ['people'] });
|
|
1646
|
-
* const email = result.getEmail();
|
|
1395
|
+
* const companyLookup = await ctx.tools.execute('test_company_search', { domain: 'stripe.com' });
|
|
1396
|
+
* const company = companyLookup.result.data;
|
|
1647
1397
|
* ```
|
|
1648
1398
|
*/
|
|
1649
1399
|
get tools() {
|
|
@@ -1652,10 +1402,8 @@ var DeeplineContext = class {
|
|
|
1652
1402
|
list: () => this.client.listTools(),
|
|
1653
1403
|
/** Get detailed metadata for a tool. */
|
|
1654
1404
|
get: (toolId) => this.client.getTool(toolId),
|
|
1655
|
-
/** Execute a tool and return
|
|
1656
|
-
execute: async (
|
|
1657
|
-
await this.client.executeTool(request.tool, request.input)
|
|
1658
|
-
)
|
|
1405
|
+
/** Execute a tool and return the standard execution envelope. */
|
|
1406
|
+
execute: async (toolId, input) => this.client.executeTool(toolId, input)
|
|
1659
1407
|
};
|
|
1660
1408
|
}
|
|
1661
1409
|
get plays() {
|
|
@@ -1858,6 +1606,147 @@ function getDefinedPlayMetadata(value) {
|
|
|
1858
1606
|
}
|
|
1859
1607
|
return candidate;
|
|
1860
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
|
+
}
|
|
1861
1750
|
// Annotate the CommonJS export names for ESM import in node:
|
|
1862
1751
|
0 && (module.exports = {
|
|
1863
1752
|
AuthError,
|
|
@@ -1870,7 +1759,6 @@ function getDefinedPlayMetadata(value) {
|
|
|
1870
1759
|
RateLimitError,
|
|
1871
1760
|
SDK_API_CONTRACT,
|
|
1872
1761
|
SDK_VERSION,
|
|
1873
|
-
createToolCallResult,
|
|
1874
1762
|
defineInput,
|
|
1875
1763
|
definePlay,
|
|
1876
1764
|
defineWorkflow,
|