deepline 0.1.33 → 0.1.36

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/dist/index.mjs CHANGED
@@ -169,8 +169,8 @@ function resolveConfig(options) {
169
169
  }
170
170
 
171
171
  // src/version.ts
172
- var SDK_VERSION = "0.1.33";
173
- var SDK_API_CONTRACT = "2026-05-host-env-generic-play-input-flags";
172
+ var SDK_VERSION = "0.1.36";
173
+ var SDK_API_CONTRACT = "2026-05-v2-tool-response";
174
174
 
175
175
  // ../shared_libs/play-runtime/coordinator-headers.ts
176
176
  var COORDINATOR_INTERNAL_TOKEN_HEADER = "x-deepline-internal-token";
@@ -252,7 +252,7 @@ var HttpClient = class {
252
252
  const response = await fetch(candidateUrl, {
253
253
  method,
254
254
  headers,
255
- body: options?.formData !== void 0 ? options.formData : options?.body !== void 0 ? JSON.stringify(options.body) : void 0,
255
+ body: options?.formData !== void 0 ? typeof options.formData === "function" ? options.formData() : options.formData : options?.body !== void 0 ? JSON.stringify(options.body) : void 0,
256
256
  signal: controller.signal
257
257
  });
258
258
  clearTimeout(timeoutId);
@@ -335,10 +335,13 @@ var HttpClient = class {
335
335
  throw new AuthError();
336
336
  }
337
337
  if (!response.ok) {
338
+ const body = await response.text();
339
+ const parsed = parseResponseBody(body);
338
340
  throw new DeeplineError(
339
- `HTTP ${response.status}`,
341
+ apiErrorMessage(parsed, response.status),
340
342
  response.status,
341
- "API_ERROR"
343
+ "API_ERROR",
344
+ { response: parsed }
342
345
  );
343
346
  }
344
347
  if (!response.body) {
@@ -388,6 +391,26 @@ var HttpClient = class {
388
391
  return this.request(path, { method: "DELETE" });
389
392
  }
390
393
  };
394
+ function parseResponseBody(body) {
395
+ try {
396
+ return JSON.parse(body);
397
+ } catch {
398
+ return body;
399
+ }
400
+ }
401
+ function apiErrorMessage(parsed, status) {
402
+ const errorValue = typeof parsed === "object" && parsed && "error" in parsed ? parsed.error : void 0;
403
+ if (typeof errorValue === "string") {
404
+ return errorValue;
405
+ }
406
+ if (errorValue && typeof errorValue === "object" && "message" in errorValue && typeof errorValue.message === "string") {
407
+ return errorValue.message;
408
+ }
409
+ if (typeof parsed === "object" && parsed && "message" in parsed && typeof parsed.message === "string") {
410
+ return parsed.message;
411
+ }
412
+ return `HTTP ${status}`;
413
+ }
391
414
  function parseRetryAfter(response) {
392
415
  const header = response.headers.get("retry-after");
393
416
  if (header) {
@@ -457,6 +480,8 @@ function sleep(ms) {
457
480
  // src/client.ts
458
481
  var TERMINAL_PLAY_STATUSES = /* @__PURE__ */ new Set(["completed", "failed", "cancelled"]);
459
482
  var INCLUDE_TOOL_METADATA_HEADER = "x-deepline-include-tool-metadata";
483
+ var EXECUTE_RESPONSE_CONTRACT_HEADER = "x-deepline-execute-response-contract";
484
+ var V2_EXECUTE_RESPONSE_CONTRACT = "v2-tool-response";
460
485
  var COMPILE_MANIFEST_RETRY_DELAYS_MS = [250, 1e3];
461
486
  function sleep2(ms) {
462
487
  return new Promise((resolve2) => setTimeout(resolve2, ms));
@@ -725,13 +750,16 @@ var DeeplineClient = class {
725
750
  /**
726
751
  * Execute a tool and return the standard execution envelope.
727
752
  *
728
- * The `result.data` field contains the provider payload. `result.meta`
729
- * contains provider/upstream metadata such as HTTP status or paging details.
753
+ * The `toolResponse.raw` field contains the raw tool response.
754
+ * `toolResponse.meta` contains tool/provider metadata.
730
755
  * Top-level fields such as `status`, `job_id`, and `billing` describe the
731
- * Deepline execution.
756
+ * Deepline execution envelope.
732
757
  */
733
758
  async executeTool(toolId, input, options) {
734
- const headers = options?.includeToolMetadata ? { [INCLUDE_TOOL_METADATA_HEADER]: "true" } : void 0;
759
+ const headers = {
760
+ [EXECUTE_RESPONSE_CONTRACT_HEADER]: V2_EXECUTE_RESPONSE_CONTRACT,
761
+ ...options?.includeToolMetadata ? { [INCLUDE_TOOL_METADATA_HEADER]: "true" } : {}
762
+ };
735
763
  return this.http.post(
736
764
  `/api/v2/integrations/${encodeURIComponent(toolId)}/execute`,
737
765
  { payload: input },
@@ -1029,34 +1057,37 @@ var DeeplineClient = class {
1029
1057
  * ```
1030
1058
  */
1031
1059
  async stagePlayFiles(files) {
1032
- const formData = new FormData();
1033
- formData.set(
1034
- "metadata",
1035
- JSON.stringify({
1036
- files: files.map((file, index) => ({
1037
- index,
1038
- logicalPath: file.logicalPath,
1039
- contentHash: file.contentHash,
1040
- contentType: file.contentType,
1041
- bytes: file.bytes
1042
- }))
1043
- })
1044
- );
1045
- for (const [index, file] of files.entries()) {
1046
- const bytes = decodeBase64Bytes(file.contentBase64);
1047
- const body = bytes.buffer.slice(
1048
- bytes.byteOffset,
1049
- bytes.byteOffset + bytes.byteLength
1050
- );
1060
+ const buildFormData = () => {
1061
+ const formData = new FormData();
1051
1062
  formData.set(
1052
- `file:${index}`,
1053
- new Blob([body], { type: file.contentType }),
1054
- file.logicalPath
1063
+ "metadata",
1064
+ JSON.stringify({
1065
+ files: files.map((file, index) => ({
1066
+ index,
1067
+ logicalPath: file.logicalPath,
1068
+ contentHash: file.contentHash,
1069
+ contentType: file.contentType,
1070
+ bytes: file.bytes
1071
+ }))
1072
+ })
1055
1073
  );
1056
- }
1074
+ for (const [index, file] of files.entries()) {
1075
+ const bytes = decodeBase64Bytes(file.contentBase64);
1076
+ const body = bytes.buffer.slice(
1077
+ bytes.byteOffset,
1078
+ bytes.byteOffset + bytes.byteLength
1079
+ );
1080
+ formData.set(
1081
+ `file:${index}`,
1082
+ new Blob([body], { type: file.contentType }),
1083
+ file.logicalPath
1084
+ );
1085
+ }
1086
+ return formData;
1087
+ };
1057
1088
  const response = await this.http.postFormData(
1058
1089
  "/api/v2/plays/files/stage",
1059
- formData
1090
+ buildFormData
1060
1091
  );
1061
1092
  return response.files;
1062
1093
  }
@@ -1530,6 +1561,391 @@ var DeeplineClient = class {
1530
1561
  }
1531
1562
  };
1532
1563
 
1564
+ // ../shared_libs/play-runtime/tool-result.ts
1565
+ var TARGET_FALLBACK_KEYS = {
1566
+ email: [/^email$/i, /^address$/i, /email/i],
1567
+ phone: [/^phone$/i, /mobile/i, /phone/i, /telephone/i],
1568
+ linkedin: [/^linkedin_url$/i, /^linkedin$/i, /linkedin/i],
1569
+ company_linkedin_url: [/company.*linkedin/i, /linkedin.*company/i],
1570
+ company_domain: [/^company_domain$/i, /company.*domain/i],
1571
+ company_name: [/^company_name$/i, /company.*name/i],
1572
+ domain: [/^domain$/i, /company_domain/i, /domain/i],
1573
+ status: [/^email_status$/i, /^status$/i],
1574
+ email_status: [/^email_status$/i, /^status$/i]
1575
+ };
1576
+ function isRecord2(value) {
1577
+ return Boolean(value) && typeof value === "object" && !Array.isArray(value);
1578
+ }
1579
+ function toV2RawToolOutputPath(path) {
1580
+ const normalized = String(path || "").trim().replace(/^\./, "");
1581
+ if (!normalized) return "toolResponse.raw";
1582
+ if (normalized === "toolResponse.raw" || normalized.startsWith("toolResponse.raw.")) {
1583
+ return normalized;
1584
+ }
1585
+ const rawPath = normalized.replace(/^result\.data\.?/, "").replace(/^result\.?/, "").replace(/^data\.?/, "").replace(/^\./, "");
1586
+ return rawPath ? `toolResponse.raw.${rawPath}` : "toolResponse.raw";
1587
+ }
1588
+ function isMeaningfulValue(value) {
1589
+ if (value == null) return false;
1590
+ if (typeof value === "string") return value.trim().length > 0;
1591
+ if (Array.isArray(value)) return value.length > 0;
1592
+ if (typeof value === "object") return Object.keys(value).length > 0;
1593
+ return true;
1594
+ }
1595
+ function parsePath(path) {
1596
+ const segments = [];
1597
+ for (const rawPart of path.split(".").filter(Boolean)) {
1598
+ const bracketPattern = /([^\[\]]+)|\[(\d+|\*)\]/g;
1599
+ let matched = false;
1600
+ for (const match of rawPart.matchAll(bracketPattern)) {
1601
+ matched = true;
1602
+ if (match[1]) {
1603
+ segments.push(match[1]);
1604
+ } else if (match[2] === "*") {
1605
+ segments.push("*");
1606
+ } else if (match[2]) {
1607
+ segments.push(Number(match[2]));
1608
+ }
1609
+ }
1610
+ if (!matched) {
1611
+ segments.push(rawPart);
1612
+ }
1613
+ }
1614
+ return segments;
1615
+ }
1616
+ function pathToString(segments) {
1617
+ return segments.map(
1618
+ (segment, index) => typeof segment === "number" ? `[${segment}]` : segment === "*" ? "[*]" : index === 0 ? segment : `.${segment}`
1619
+ ).join("");
1620
+ }
1621
+ function valuesAtSegments(current, segments, path = []) {
1622
+ if (segments.length === 0) {
1623
+ return [{ value: current, path: pathToString(path) }];
1624
+ }
1625
+ const [segment, ...rest] = segments;
1626
+ if (segment === "*") {
1627
+ if (!Array.isArray(current)) return [];
1628
+ return current.flatMap(
1629
+ (entry, index) => valuesAtSegments(entry, rest, [...path, index])
1630
+ );
1631
+ }
1632
+ if (typeof segment === "number") {
1633
+ if (!Array.isArray(current)) return [];
1634
+ return valuesAtSegments(current[segment], rest, [...path, segment]);
1635
+ }
1636
+ if (!isRecord2(current)) return [];
1637
+ return valuesAtSegments(current[segment], rest, [...path, segment]);
1638
+ }
1639
+ function getValuesAtPath(root, path) {
1640
+ return valuesAtSegments(root, parsePath(path)).map((entry) => entry.value);
1641
+ }
1642
+ function toResultEnvelope(value) {
1643
+ if (isRecord2(value) && "data" in value) {
1644
+ const envelope = { data: value.data };
1645
+ if ("meta" in value) envelope.meta = value.meta;
1646
+ return envelope;
1647
+ }
1648
+ return { data: value };
1649
+ }
1650
+ function normalizeResultPath(path) {
1651
+ const trimmed = String(path || "").trim().replace(/^\./, "");
1652
+ if (!trimmed) return "";
1653
+ return toV2RawToolOutputPath(trimmed);
1654
+ }
1655
+ function toV2RawToolOutputPathPreservingProviderData(path) {
1656
+ const normalized = String(path || "").trim().replace(/^\./, "");
1657
+ if (!normalized) return "toolResponse.raw";
1658
+ if (normalized === "toolResponse.raw" || normalized.startsWith("toolResponse.raw.")) {
1659
+ return normalized;
1660
+ }
1661
+ const rawPath = normalized.replace(/^result\.?/, "").replace(/^\./, "");
1662
+ return rawPath ? `toolResponse.raw.${rawPath}` : "toolResponse.raw";
1663
+ }
1664
+ function candidateResultPaths(path) {
1665
+ const candidates = [
1666
+ normalizeResultPath(path),
1667
+ toV2RawToolOutputPathPreservingProviderData(path)
1668
+ ];
1669
+ return candidates.filter(
1670
+ (candidate, index, all) => candidate.length > 0 && all.indexOf(candidate) === index
1671
+ );
1672
+ }
1673
+ function normalizeRelativePath(path) {
1674
+ return String(path || "").trim().replace(/^result\./, "").replace(/^\./, "");
1675
+ }
1676
+ function getFirstMeaningfulValueAtPath(root, path) {
1677
+ for (const entry of valuesAtSegments(root, parsePath(path))) {
1678
+ if (isMeaningfulValue(entry.value)) {
1679
+ return { value: entry.value, path: entry.path };
1680
+ }
1681
+ }
1682
+ return null;
1683
+ }
1684
+ function getAtPath(root, path) {
1685
+ const segments = parsePath(path);
1686
+ if (segments.includes("*")) {
1687
+ return getValuesAtPath(root, path).filter(isMeaningfulValue);
1688
+ }
1689
+ let current = root;
1690
+ for (const segment of segments) {
1691
+ if (typeof segment === "number") {
1692
+ if (!Array.isArray(current)) return void 0;
1693
+ current = current[segment];
1694
+ continue;
1695
+ }
1696
+ if (!isRecord2(current)) return void 0;
1697
+ current = current[segment];
1698
+ }
1699
+ return current;
1700
+ }
1701
+ function normalizeRows(value) {
1702
+ if (!Array.isArray(value)) return null;
1703
+ return value.map((entry) => isRecord2(entry) ? entry : { value: entry });
1704
+ }
1705
+ function findFirstTargetByPath(result, paths) {
1706
+ for (const path of paths ?? []) {
1707
+ for (const candidate of candidateResultPaths(path)) {
1708
+ const match = getFirstMeaningfulValueAtPath(result, candidate);
1709
+ if (match) return match;
1710
+ }
1711
+ }
1712
+ return null;
1713
+ }
1714
+ function findFirstTargetByKey(result, target, depth = 0, path = []) {
1715
+ if (depth > 6) return null;
1716
+ if (Array.isArray(result)) {
1717
+ for (let index = 0; index < result.length; index += 1) {
1718
+ const found = findFirstTargetByKey(result[index], target, depth + 1, [
1719
+ ...path,
1720
+ index
1721
+ ]);
1722
+ if (found) return found;
1723
+ }
1724
+ return null;
1725
+ }
1726
+ if (!isRecord2(result)) return null;
1727
+ const patterns = TARGET_FALLBACK_KEYS[target] ?? [
1728
+ new RegExp(`^${target}$`, "i")
1729
+ ];
1730
+ for (const [key, value] of Object.entries(result)) {
1731
+ if (patterns.some((pattern) => pattern.test(key)) && isMeaningfulValue(value)) {
1732
+ return { value, path: pathToString([...path, key]) };
1733
+ }
1734
+ }
1735
+ for (const [key, value] of Object.entries(result)) {
1736
+ const found = findFirstTargetByKey(value, target, depth + 1, [
1737
+ ...path,
1738
+ key
1739
+ ]);
1740
+ if (found) return found;
1741
+ }
1742
+ return null;
1743
+ }
1744
+ function resolveListRows(result, listExtractorPaths) {
1745
+ const lists = {};
1746
+ for (const rawPath of listExtractorPaths ?? []) {
1747
+ const path = normalizeResultPath(rawPath);
1748
+ if (!path) continue;
1749
+ const candidates = [
1750
+ ...candidateResultPaths(rawPath)
1751
+ ].filter(
1752
+ (candidate, index, all) => candidate && all.indexOf(candidate) === index
1753
+ );
1754
+ let resolvedPath = null;
1755
+ let rows = null;
1756
+ for (const candidate of candidates) {
1757
+ rows = normalizeRows(getAtPath(result, candidate));
1758
+ if (rows) {
1759
+ resolvedPath = candidate;
1760
+ break;
1761
+ }
1762
+ }
1763
+ if (!rows) continue;
1764
+ const storedPath = resolvedPath ?? path;
1765
+ const name = storedPath.split(".").filter(Boolean).at(-1)?.replace(/\[\d+\]$/, "");
1766
+ lists[name || storedPath] = { path: storedPath, rows };
1767
+ }
1768
+ return lists;
1769
+ }
1770
+ function deriveListKeys(input) {
1771
+ const keys = {};
1772
+ for (const [target, paths] of Object.entries(
1773
+ input.listIdentityGetters ?? {}
1774
+ )) {
1775
+ const firstPath = paths.map(
1776
+ (rawPath) => normalizeRelativePath(rawPath)
1777
+ ).find(Boolean);
1778
+ if (firstPath) {
1779
+ keys[target] = firstPath;
1780
+ }
1781
+ }
1782
+ if (Object.keys(keys).length > 0) {
1783
+ return keys;
1784
+ }
1785
+ const listPrefix = input.listPath.replace(/\[\d+\]$/, "");
1786
+ for (const [target, paths] of Object.entries(
1787
+ input.resultIdentityGetters ?? {}
1788
+ )) {
1789
+ for (const rawPath of paths) {
1790
+ const path = String(rawPath || "").trim().replace(/^\./, "");
1791
+ if (!path) continue;
1792
+ for (const resultPath of candidateResultPaths(path)) {
1793
+ const directPrefix = `${listPrefix}.`;
1794
+ if (resultPath.startsWith(directPrefix)) {
1795
+ keys[target] = resultPath.slice(directPrefix.length).replace(/^\[\d+\]\.?/, "");
1796
+ break;
1797
+ }
1798
+ const indexedPrefix = `${listPrefix}[0].`;
1799
+ if (resultPath.startsWith(indexedPrefix)) {
1800
+ keys[target] = resultPath.slice(indexedPrefix.length);
1801
+ break;
1802
+ }
1803
+ const wildcardPrefix = `${listPrefix}[*].`;
1804
+ if (resultPath.startsWith(wildcardPrefix)) {
1805
+ keys[target] = resultPath.slice(wildcardPrefix.length);
1806
+ break;
1807
+ }
1808
+ const dottedIndexPrefix = `${listPrefix}.0.`;
1809
+ if (resultPath.startsWith(dottedIndexPrefix)) {
1810
+ keys[target] = resultPath.slice(dottedIndexPrefix.length);
1811
+ break;
1812
+ }
1813
+ }
1814
+ if (keys[target]) break;
1815
+ }
1816
+ }
1817
+ if (Object.keys(keys).length === 0 && input.rows[0]) {
1818
+ for (const key of Object.keys(input.rows[0])) {
1819
+ keys[key] = key;
1820
+ }
1821
+ }
1822
+ return keys;
1823
+ }
1824
+ function buildTargets(result, resultIdentityGetters) {
1825
+ const targets = {};
1826
+ const metadataTargets = new Set(Object.keys(resultIdentityGetters ?? {}));
1827
+ for (const target of metadataTargets) {
1828
+ const fromMetadata = findFirstTargetByPath(
1829
+ result,
1830
+ resultIdentityGetters?.[target]
1831
+ );
1832
+ if (fromMetadata) {
1833
+ targets[target] = fromMetadata;
1834
+ continue;
1835
+ }
1836
+ const fallback = findFirstTargetByKey(result, target);
1837
+ if (fallback) {
1838
+ targets[target] = fallback;
1839
+ }
1840
+ }
1841
+ if (metadataTargets.size > 0) return targets;
1842
+ for (const target of ["email", "phone", "linkedin", "domain", "status"]) {
1843
+ const found = findFirstTargetByKey(result, target);
1844
+ if (found) targets[target] = found;
1845
+ }
1846
+ return targets;
1847
+ }
1848
+ function buildLists(result, metadata) {
1849
+ const lists = {};
1850
+ const resolved = resolveListRows(result, metadata.listExtractorPaths);
1851
+ for (const [name, list] of Object.entries(resolved)) {
1852
+ lists[name] = {
1853
+ path: list.path,
1854
+ count: list.rows.length,
1855
+ keys: deriveListKeys({
1856
+ listPath: list.path,
1857
+ rows: list.rows,
1858
+ resultIdentityGetters: metadata.resultIdentityGetters,
1859
+ listIdentityGetters: metadata.listIdentityGetters
1860
+ })
1861
+ };
1862
+ }
1863
+ return lists;
1864
+ }
1865
+ function buildExtractedAccessors(targets) {
1866
+ return Object.fromEntries(
1867
+ Object.entries(targets).map(([target, metadata]) => {
1868
+ const accessor = { path: metadata.path };
1869
+ Object.defineProperties(accessor, {
1870
+ value: {
1871
+ value: metadata.value,
1872
+ enumerable: false
1873
+ },
1874
+ get: {
1875
+ value() {
1876
+ return metadata.value ?? null;
1877
+ },
1878
+ enumerable: false
1879
+ }
1880
+ });
1881
+ return [target, accessor];
1882
+ })
1883
+ );
1884
+ }
1885
+ function buildListAccessors(result, lists) {
1886
+ return Object.fromEntries(
1887
+ Object.entries(lists).map(([name, metadata]) => {
1888
+ const accessor = {
1889
+ path: metadata.path,
1890
+ count: metadata.count,
1891
+ keys: metadata.keys
1892
+ };
1893
+ Object.defineProperty(accessor, "get", {
1894
+ value() {
1895
+ return normalizeRows(getAtPath(result, metadata.path)) ?? [];
1896
+ },
1897
+ enumerable: false
1898
+ });
1899
+ return [name, accessor];
1900
+ })
1901
+ );
1902
+ }
1903
+ function createToolExecuteResult(input) {
1904
+ const result = toResultEnvelope(input.result);
1905
+ const resultRoot = {
1906
+ toolResponse: {
1907
+ raw: result.data,
1908
+ ...result.meta ? { meta: result.meta } : {}
1909
+ }
1910
+ };
1911
+ const targets = buildTargets(
1912
+ resultRoot,
1913
+ input.metadata.resultIdentityGetters
1914
+ );
1915
+ const lists = buildLists(resultRoot, input.metadata);
1916
+ const metadata = {
1917
+ toolId: input.metadata.toolId,
1918
+ execution: input.execution,
1919
+ targets,
1920
+ lists
1921
+ };
1922
+ const toolResponse = {
1923
+ raw: result.data,
1924
+ ...result.meta ? { meta: result.meta } : {}
1925
+ };
1926
+ const extractedValues = buildExtractedAccessors(targets);
1927
+ const extractedLists = buildListAccessors(resultRoot, lists);
1928
+ const wrapper = {
1929
+ status: input.status,
1930
+ ...input.jobId ? { job_id: input.jobId } : {},
1931
+ ...input.meta ? { meta: input.meta } : {},
1932
+ toolResponse,
1933
+ extractedValues,
1934
+ extractedLists
1935
+ };
1936
+ Object.defineProperties(wrapper, {
1937
+ toolOutput: {
1938
+ value: toolResponse,
1939
+ enumerable: false
1940
+ }
1941
+ });
1942
+ Object.defineProperty(wrapper, "_metadata", {
1943
+ value: metadata,
1944
+ enumerable: false
1945
+ });
1946
+ return wrapper;
1947
+ }
1948
+
1533
1949
  // src/play.ts
1534
1950
  var DeeplineConditionalStepResolver = class _DeeplineConditionalStepResolver {
1535
1951
  constructor(when2, run, elseValue) {
@@ -1666,10 +2082,10 @@ var DeeplineContext = class {
1666
2082
  *
1667
2083
  * @example
1668
2084
  * ```typescript
1669
- * const tools = await ctx.tools.list();
1670
- * const meta = await ctx.tools.get('apollo_people_search');
1671
- * const companyLookup = await ctx.tools.execute('test_company_search', { domain: 'stripe.com' });
1672
- * const company = companyLookup.result.data;
2085
+ * const tools = await deepline.tools.list();
2086
+ * const meta = await deepline.tools.get('apollo_people_search');
2087
+ * const companyLookup = await deepline.tools.execute('test_company_search', { domain: 'stripe.com' });
2088
+ * const company = companyLookup.toolResponse.raw;
1673
2089
  * ```
1674
2090
  */
1675
2091
  get tools() {
@@ -1679,11 +2095,14 @@ var DeeplineContext = class {
1679
2095
  /** Get detailed metadata for a tool. */
1680
2096
  get: (toolId) => this.client.getTool(toolId),
1681
2097
  /** Execute a tool and return the standard execution envelope. */
1682
- execute: async (toolId, input) => this.client.executeTool(
1683
- toolId,
1684
- input,
1685
- { includeToolMetadata: true }
1686
- )
2098
+ execute: async (toolId, input) => {
2099
+ const response = await this.client.executeTool(
2100
+ toolId,
2101
+ input,
2102
+ { includeToolMetadata: true }
2103
+ );
2104
+ return toolExecutionEnvelopeToResult(toolId, response);
2105
+ }
1687
2106
  };
1688
2107
  }
1689
2108
  get plays() {
@@ -1778,6 +2197,49 @@ var Deepline = class {
1778
2197
  return new DeeplineContext(options);
1779
2198
  }
1780
2199
  };
2200
+ function isRecord3(value) {
2201
+ return Boolean(value) && typeof value === "object" && !Array.isArray(value);
2202
+ }
2203
+ function stringArrayRecord(value) {
2204
+ if (!isRecord3(value)) return {};
2205
+ return Object.fromEntries(
2206
+ Object.entries(value).map(([key, paths]) => [
2207
+ key,
2208
+ Array.isArray(paths) ? paths.map(String) : []
2209
+ ])
2210
+ );
2211
+ }
2212
+ function stringArray(value) {
2213
+ return Array.isArray(value) ? value.map(String) : [];
2214
+ }
2215
+ function toolExecutionEnvelopeToResult(fallbackToolId, response) {
2216
+ const raw = response.toolResponse?.raw ?? null;
2217
+ const meta = response.toolResponse?.meta;
2218
+ const metadata = isRecord3(response._metadata) ? response._metadata.tool : null;
2219
+ const toolMetadata = isRecord3(metadata) ? metadata : {};
2220
+ return createToolExecuteResult({
2221
+ status: typeof response.status === "string" ? response.status : "completed",
2222
+ jobId: typeof response.job_id === "string" ? response.job_id : void 0,
2223
+ result: {
2224
+ data: raw,
2225
+ ...isRecord3(meta) ? { meta } : {}
2226
+ },
2227
+ metadata: {
2228
+ toolId: typeof toolMetadata.toolId === "string" ? toolMetadata.toolId : fallbackToolId,
2229
+ resultIdentityGetters: stringArrayRecord(
2230
+ toolMetadata.resultIdentityGetters
2231
+ ),
2232
+ listExtractorPaths: stringArray(toolMetadata.listExtractorPaths),
2233
+ listIdentityGetters: stringArrayRecord(toolMetadata.listIdentityGetters)
2234
+ },
2235
+ execution: {
2236
+ idempotent: true,
2237
+ cached: false,
2238
+ source: "live"
2239
+ },
2240
+ meta: isRecord3(response.meta) ? response.meta : void 0
2241
+ });
2242
+ }
1781
2243
  function defineInput(schema) {
1782
2244
  if (!schema || typeof schema !== "object" || Array.isArray(schema)) {
1783
2245
  throw new Error(
@@ -1904,7 +2366,7 @@ function getByDottedPath(root, dottedPath) {
1904
2366
  }
1905
2367
  return current;
1906
2368
  }
1907
- function normalizeRows(value) {
2369
+ function normalizeRows2(value) {
1908
2370
  if (!Array.isArray(value)) return null;
1909
2371
  return value.map((entry) => {
1910
2372
  if (isPlainObject(entry)) return entry;
@@ -1913,6 +2375,21 @@ function normalizeRows(value) {
1913
2375
  }
1914
2376
  function candidateRoots(payload) {
1915
2377
  const roots = [{ path: null, value: payload }];
2378
+ if (isPlainObject(payload) && isPlainObject(payload.toolResponse)) {
2379
+ roots.push({ path: "toolResponse", value: payload.toolResponse });
2380
+ if (Object.prototype.hasOwnProperty.call(payload.toolResponse, "raw")) {
2381
+ roots.push({
2382
+ path: "toolResponse.raw",
2383
+ value: payload.toolResponse.raw
2384
+ });
2385
+ }
2386
+ }
2387
+ if (isPlainObject(payload) && isPlainObject(payload.output)) {
2388
+ roots.push({ path: "output", value: payload.output });
2389
+ if (Object.prototype.hasOwnProperty.call(payload.output, "body")) {
2390
+ roots.push({ path: "output.body", value: payload.output.body });
2391
+ }
2392
+ }
1916
2393
  if (isPlainObject(payload) && isPlainObject(payload.result)) {
1917
2394
  roots.push({ path: "result", value: payload.result });
1918
2395
  if (isPlainObject(payload.result.data)) {
@@ -1923,7 +2400,7 @@ function candidateRoots(payload) {
1923
2400
  }
1924
2401
  function findBestArrayCandidate(value, pathPrefix = "", depth = 0) {
1925
2402
  if (depth > 5) return null;
1926
- const directRows = normalizeRows(value);
2403
+ const directRows = normalizeRows2(value);
1927
2404
  const hasObjectRow = directRows?.some((row) => Object.keys(row).some((key) => key !== "value")) ?? false;
1928
2405
  let best = directRows && directRows.length > 0 && hasObjectRow ? { path: pathPrefix, rows: directRows } : null;
1929
2406
  if (!isPlainObject(value)) {
@@ -1945,7 +2422,7 @@ function tryConvertToList(payload, options) {
1945
2422
  for (const root of candidateRoots(payload)) {
1946
2423
  for (const extractorPath of listExtractorPaths) {
1947
2424
  const resolved = getByDottedPath(root.value, extractorPath);
1948
- const rows = normalizeRows(resolved);
2425
+ const rows = normalizeRows2(resolved);
1949
2426
  if (rows && rows.length > 0) {
1950
2427
  const sourcePath = root.path ? `${root.path}.${extractorPath}` : extractorPath;
1951
2428
  return { rows, strategy: "configured_paths", sourcePath };