deepline 0.1.33 → 0.1.35

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.js CHANGED
@@ -215,8 +215,8 @@ function resolveConfig(options) {
215
215
  }
216
216
 
217
217
  // src/version.ts
218
- var SDK_VERSION = "0.1.33";
219
- var SDK_API_CONTRACT = "2026-05-host-env-generic-play-input-flags";
218
+ var SDK_VERSION = "0.1.35";
219
+ var SDK_API_CONTRACT = "2026-05-v2-tool-result-contract";
220
220
 
221
221
  // ../shared_libs/play-runtime/coordinator-headers.ts
222
222
  var COORDINATOR_INTERNAL_TOKEN_HEADER = "x-deepline-internal-token";
@@ -298,7 +298,7 @@ var HttpClient = class {
298
298
  const response = await fetch(candidateUrl, {
299
299
  method,
300
300
  headers,
301
- body: options?.formData !== void 0 ? options.formData : options?.body !== void 0 ? JSON.stringify(options.body) : void 0,
301
+ body: options?.formData !== void 0 ? typeof options.formData === "function" ? options.formData() : options.formData : options?.body !== void 0 ? JSON.stringify(options.body) : void 0,
302
302
  signal: controller.signal
303
303
  });
304
304
  clearTimeout(timeoutId);
@@ -381,10 +381,13 @@ var HttpClient = class {
381
381
  throw new AuthError();
382
382
  }
383
383
  if (!response.ok) {
384
+ const body = await response.text();
385
+ const parsed = parseResponseBody(body);
384
386
  throw new DeeplineError(
385
- `HTTP ${response.status}`,
387
+ apiErrorMessage(parsed, response.status),
386
388
  response.status,
387
- "API_ERROR"
389
+ "API_ERROR",
390
+ { response: parsed }
388
391
  );
389
392
  }
390
393
  if (!response.body) {
@@ -434,6 +437,26 @@ var HttpClient = class {
434
437
  return this.request(path, { method: "DELETE" });
435
438
  }
436
439
  };
440
+ function parseResponseBody(body) {
441
+ try {
442
+ return JSON.parse(body);
443
+ } catch {
444
+ return body;
445
+ }
446
+ }
447
+ function apiErrorMessage(parsed, status) {
448
+ const errorValue = typeof parsed === "object" && parsed && "error" in parsed ? parsed.error : void 0;
449
+ if (typeof errorValue === "string") {
450
+ return errorValue;
451
+ }
452
+ if (errorValue && typeof errorValue === "object" && "message" in errorValue && typeof errorValue.message === "string") {
453
+ return errorValue.message;
454
+ }
455
+ if (typeof parsed === "object" && parsed && "message" in parsed && typeof parsed.message === "string") {
456
+ return parsed.message;
457
+ }
458
+ return `HTTP ${status}`;
459
+ }
437
460
  function parseRetryAfter(response) {
438
461
  const header = response.headers.get("retry-after");
439
462
  if (header) {
@@ -503,6 +526,8 @@ function sleep(ms) {
503
526
  // src/client.ts
504
527
  var TERMINAL_PLAY_STATUSES = /* @__PURE__ */ new Set(["completed", "failed", "cancelled"]);
505
528
  var INCLUDE_TOOL_METADATA_HEADER = "x-deepline-include-tool-metadata";
529
+ var EXECUTE_RESPONSE_CONTRACT_HEADER = "x-deepline-execute-response-contract";
530
+ var V2_EXECUTE_RESPONSE_CONTRACT = "v2-tool-execution-result";
506
531
  var COMPILE_MANIFEST_RETRY_DELAYS_MS = [250, 1e3];
507
532
  function sleep2(ms) {
508
533
  return new Promise((resolve2) => setTimeout(resolve2, ms));
@@ -771,13 +796,16 @@ var DeeplineClient = class {
771
796
  /**
772
797
  * Execute a tool and return the standard execution envelope.
773
798
  *
774
- * The `result.data` field contains the provider payload. `result.meta`
775
- * contains provider/upstream metadata such as HTTP status or paging details.
799
+ * The `toolExecutionResult.toolOutput.raw` field contains the raw tool output.
800
+ * `toolExecutionResult.toolOutput.meta` contains tool/provider metadata.
776
801
  * Top-level fields such as `status`, `job_id`, and `billing` describe the
777
- * Deepline execution.
802
+ * Deepline execution envelope.
778
803
  */
779
804
  async executeTool(toolId, input, options) {
780
- const headers = options?.includeToolMetadata ? { [INCLUDE_TOOL_METADATA_HEADER]: "true" } : void 0;
805
+ const headers = {
806
+ [EXECUTE_RESPONSE_CONTRACT_HEADER]: V2_EXECUTE_RESPONSE_CONTRACT,
807
+ ...options?.includeToolMetadata ? { [INCLUDE_TOOL_METADATA_HEADER]: "true" } : {}
808
+ };
781
809
  return this.http.post(
782
810
  `/api/v2/integrations/${encodeURIComponent(toolId)}/execute`,
783
811
  { payload: input },
@@ -1075,34 +1103,37 @@ var DeeplineClient = class {
1075
1103
  * ```
1076
1104
  */
1077
1105
  async stagePlayFiles(files) {
1078
- const formData = new FormData();
1079
- formData.set(
1080
- "metadata",
1081
- JSON.stringify({
1082
- files: files.map((file, index) => ({
1083
- index,
1084
- logicalPath: file.logicalPath,
1085
- contentHash: file.contentHash,
1086
- contentType: file.contentType,
1087
- bytes: file.bytes
1088
- }))
1089
- })
1090
- );
1091
- for (const [index, file] of files.entries()) {
1092
- const bytes = decodeBase64Bytes(file.contentBase64);
1093
- const body = bytes.buffer.slice(
1094
- bytes.byteOffset,
1095
- bytes.byteOffset + bytes.byteLength
1096
- );
1106
+ const buildFormData = () => {
1107
+ const formData = new FormData();
1097
1108
  formData.set(
1098
- `file:${index}`,
1099
- new Blob([body], { type: file.contentType }),
1100
- file.logicalPath
1109
+ "metadata",
1110
+ JSON.stringify({
1111
+ files: files.map((file, index) => ({
1112
+ index,
1113
+ logicalPath: file.logicalPath,
1114
+ contentHash: file.contentHash,
1115
+ contentType: file.contentType,
1116
+ bytes: file.bytes
1117
+ }))
1118
+ })
1101
1119
  );
1102
- }
1120
+ for (const [index, file] of files.entries()) {
1121
+ const bytes = decodeBase64Bytes(file.contentBase64);
1122
+ const body = bytes.buffer.slice(
1123
+ bytes.byteOffset,
1124
+ bytes.byteOffset + bytes.byteLength
1125
+ );
1126
+ formData.set(
1127
+ `file:${index}`,
1128
+ new Blob([body], { type: file.contentType }),
1129
+ file.logicalPath
1130
+ );
1131
+ }
1132
+ return formData;
1133
+ };
1103
1134
  const response = await this.http.postFormData(
1104
1135
  "/api/v2/plays/files/stage",
1105
- formData
1136
+ buildFormData
1106
1137
  );
1107
1138
  return response.files;
1108
1139
  }
@@ -1576,6 +1607,383 @@ var DeeplineClient = class {
1576
1607
  }
1577
1608
  };
1578
1609
 
1610
+ // ../shared_libs/play-runtime/tool-result.ts
1611
+ var TARGET_FALLBACK_KEYS = {
1612
+ email: [/^email$/i, /^address$/i, /email/i],
1613
+ phone: [/^phone$/i, /mobile/i, /phone/i, /telephone/i],
1614
+ linkedin: [/^linkedin_url$/i, /^linkedin$/i, /linkedin/i],
1615
+ company_linkedin_url: [/company.*linkedin/i, /linkedin.*company/i],
1616
+ company_domain: [/^company_domain$/i, /company.*domain/i],
1617
+ company_name: [/^company_name$/i, /company.*name/i],
1618
+ domain: [/^domain$/i, /company_domain/i, /domain/i],
1619
+ status: [/^email_status$/i, /^status$/i],
1620
+ email_status: [/^email_status$/i, /^status$/i]
1621
+ };
1622
+ function isRecord2(value) {
1623
+ return Boolean(value) && typeof value === "object" && !Array.isArray(value);
1624
+ }
1625
+ function toV2RawToolOutputPath(path) {
1626
+ const normalized = String(path || "").trim().replace(/^\./, "");
1627
+ if (!normalized) return "toolExecutionResult.toolOutput.raw";
1628
+ if (normalized === "toolExecutionResult.toolOutput.raw" || normalized.startsWith("toolExecutionResult.toolOutput.raw.")) {
1629
+ return normalized;
1630
+ }
1631
+ const rawPath = normalized.replace(/^result\.data\.?/, "").replace(/^result\.?/, "").replace(/^data\.?/, "").replace(/^\./, "");
1632
+ return rawPath ? `toolExecutionResult.toolOutput.raw.${rawPath}` : "toolExecutionResult.toolOutput.raw";
1633
+ }
1634
+ function isMeaningfulValue(value) {
1635
+ if (value == null) return false;
1636
+ if (typeof value === "string") return value.trim().length > 0;
1637
+ if (Array.isArray(value)) return value.length > 0;
1638
+ if (typeof value === "object") return Object.keys(value).length > 0;
1639
+ return true;
1640
+ }
1641
+ function parsePath(path) {
1642
+ const segments = [];
1643
+ for (const rawPart of path.split(".").filter(Boolean)) {
1644
+ const bracketPattern = /([^\[\]]+)|\[(\d+|\*)\]/g;
1645
+ let matched = false;
1646
+ for (const match of rawPart.matchAll(bracketPattern)) {
1647
+ matched = true;
1648
+ if (match[1]) {
1649
+ segments.push(match[1]);
1650
+ } else if (match[2] === "*") {
1651
+ segments.push("*");
1652
+ } else if (match[2]) {
1653
+ segments.push(Number(match[2]));
1654
+ }
1655
+ }
1656
+ if (!matched) {
1657
+ segments.push(rawPart);
1658
+ }
1659
+ }
1660
+ return segments;
1661
+ }
1662
+ function pathToString(segments) {
1663
+ return segments.map(
1664
+ (segment, index) => typeof segment === "number" ? `[${segment}]` : segment === "*" ? "[*]" : index === 0 ? segment : `.${segment}`
1665
+ ).join("");
1666
+ }
1667
+ function valuesAtSegments(current, segments, path = []) {
1668
+ if (segments.length === 0) {
1669
+ return [{ value: current, path: pathToString(path) }];
1670
+ }
1671
+ const [segment, ...rest] = segments;
1672
+ if (segment === "*") {
1673
+ if (!Array.isArray(current)) return [];
1674
+ return current.flatMap(
1675
+ (entry, index) => valuesAtSegments(entry, rest, [...path, index])
1676
+ );
1677
+ }
1678
+ if (typeof segment === "number") {
1679
+ if (!Array.isArray(current)) return [];
1680
+ return valuesAtSegments(current[segment], rest, [...path, segment]);
1681
+ }
1682
+ if (!isRecord2(current)) return [];
1683
+ return valuesAtSegments(current[segment], rest, [...path, segment]);
1684
+ }
1685
+ function getValuesAtPath(root, path) {
1686
+ return valuesAtSegments(root, parsePath(path)).map((entry) => entry.value);
1687
+ }
1688
+ function toResultEnvelope(value) {
1689
+ if (isRecord2(value) && "data" in value) {
1690
+ const envelope = { data: value.data };
1691
+ if ("meta" in value) envelope.meta = value.meta;
1692
+ return envelope;
1693
+ }
1694
+ return { data: value };
1695
+ }
1696
+ function normalizeResultPath(path) {
1697
+ const trimmed = String(path || "").trim().replace(/^\./, "");
1698
+ if (!trimmed) return "";
1699
+ return toV2RawToolOutputPath(trimmed);
1700
+ }
1701
+ function toV2RawToolOutputPathPreservingProviderData(path) {
1702
+ const normalized = String(path || "").trim().replace(/^\./, "");
1703
+ if (!normalized) return "toolExecutionResult.toolOutput.raw";
1704
+ if (normalized === "toolExecutionResult.toolOutput.raw" || normalized.startsWith("toolExecutionResult.toolOutput.raw.")) {
1705
+ return normalized;
1706
+ }
1707
+ const rawPath = normalized.replace(/^result\.?/, "").replace(/^\./, "");
1708
+ return rawPath ? `toolExecutionResult.toolOutput.raw.${rawPath}` : "toolExecutionResult.toolOutput.raw";
1709
+ }
1710
+ function candidateResultPaths(path) {
1711
+ const candidates = [
1712
+ normalizeResultPath(path),
1713
+ toV2RawToolOutputPathPreservingProviderData(path)
1714
+ ];
1715
+ return candidates.filter(
1716
+ (candidate, index, all) => candidate.length > 0 && all.indexOf(candidate) === index
1717
+ );
1718
+ }
1719
+ function normalizeRelativePath(path) {
1720
+ return String(path || "").trim().replace(/^result\./, "").replace(/^\./, "");
1721
+ }
1722
+ function getFirstMeaningfulValueAtPath(root, path) {
1723
+ for (const entry of valuesAtSegments(root, parsePath(path))) {
1724
+ if (isMeaningfulValue(entry.value)) {
1725
+ return { value: entry.value, path: entry.path };
1726
+ }
1727
+ }
1728
+ return null;
1729
+ }
1730
+ function getAtPath(root, path) {
1731
+ const segments = parsePath(path);
1732
+ if (segments.includes("*")) {
1733
+ return getValuesAtPath(root, path).filter(isMeaningfulValue);
1734
+ }
1735
+ let current = root;
1736
+ for (const segment of segments) {
1737
+ if (typeof segment === "number") {
1738
+ if (!Array.isArray(current)) return void 0;
1739
+ current = current[segment];
1740
+ continue;
1741
+ }
1742
+ if (!isRecord2(current)) return void 0;
1743
+ current = current[segment];
1744
+ }
1745
+ return current;
1746
+ }
1747
+ function normalizeRows(value) {
1748
+ if (!Array.isArray(value)) return null;
1749
+ return value.map((entry) => isRecord2(entry) ? entry : { value: entry });
1750
+ }
1751
+ function findFirstTargetByPath(result, paths) {
1752
+ for (const path of paths ?? []) {
1753
+ for (const candidate of candidateResultPaths(path)) {
1754
+ const match = getFirstMeaningfulValueAtPath(result, candidate);
1755
+ if (match) return match;
1756
+ }
1757
+ }
1758
+ return null;
1759
+ }
1760
+ function findFirstTargetByKey(result, target, depth = 0, path = []) {
1761
+ if (depth > 6) return null;
1762
+ if (Array.isArray(result)) {
1763
+ for (let index = 0; index < result.length; index += 1) {
1764
+ const found = findFirstTargetByKey(result[index], target, depth + 1, [
1765
+ ...path,
1766
+ index
1767
+ ]);
1768
+ if (found) return found;
1769
+ }
1770
+ return null;
1771
+ }
1772
+ if (!isRecord2(result)) return null;
1773
+ const patterns = TARGET_FALLBACK_KEYS[target] ?? [
1774
+ new RegExp(`^${target}$`, "i")
1775
+ ];
1776
+ for (const [key, value] of Object.entries(result)) {
1777
+ if (patterns.some((pattern) => pattern.test(key)) && isMeaningfulValue(value)) {
1778
+ return { value, path: pathToString([...path, key]) };
1779
+ }
1780
+ }
1781
+ for (const [key, value] of Object.entries(result)) {
1782
+ const found = findFirstTargetByKey(value, target, depth + 1, [
1783
+ ...path,
1784
+ key
1785
+ ]);
1786
+ if (found) return found;
1787
+ }
1788
+ return null;
1789
+ }
1790
+ function resolveListRows(result, listExtractorPaths) {
1791
+ const lists = {};
1792
+ for (const rawPath of listExtractorPaths ?? []) {
1793
+ const path = normalizeResultPath(rawPath);
1794
+ if (!path) continue;
1795
+ const candidates = [
1796
+ ...candidateResultPaths(rawPath)
1797
+ ].filter(
1798
+ (candidate, index, all) => candidate && all.indexOf(candidate) === index
1799
+ );
1800
+ let resolvedPath = null;
1801
+ let rows = null;
1802
+ for (const candidate of candidates) {
1803
+ rows = normalizeRows(getAtPath(result, candidate));
1804
+ if (rows) {
1805
+ resolvedPath = candidate;
1806
+ break;
1807
+ }
1808
+ }
1809
+ if (!rows) continue;
1810
+ const storedPath = resolvedPath ?? path;
1811
+ const name = storedPath.split(".").filter(Boolean).at(-1)?.replace(/\[\d+\]$/, "");
1812
+ lists[name || storedPath] = { path: storedPath, rows };
1813
+ }
1814
+ return lists;
1815
+ }
1816
+ function deriveListKeys(input) {
1817
+ const keys = {};
1818
+ for (const [target, paths] of Object.entries(
1819
+ input.listIdentityGetters ?? {}
1820
+ )) {
1821
+ const firstPath = paths.map(
1822
+ (rawPath) => normalizeRelativePath(rawPath)
1823
+ ).find(Boolean);
1824
+ if (firstPath) {
1825
+ keys[target] = firstPath;
1826
+ }
1827
+ }
1828
+ if (Object.keys(keys).length > 0) {
1829
+ return keys;
1830
+ }
1831
+ const listPrefix = input.listPath.replace(/\[\d+\]$/, "");
1832
+ for (const [target, paths] of Object.entries(
1833
+ input.resultIdentityGetters ?? {}
1834
+ )) {
1835
+ for (const rawPath of paths) {
1836
+ const path = String(rawPath || "").trim().replace(/^\./, "");
1837
+ if (!path) continue;
1838
+ for (const resultPath of candidateResultPaths(path)) {
1839
+ const directPrefix = `${listPrefix}.`;
1840
+ if (resultPath.startsWith(directPrefix)) {
1841
+ keys[target] = resultPath.slice(directPrefix.length).replace(/^\[\d+\]\.?/, "");
1842
+ break;
1843
+ }
1844
+ const indexedPrefix = `${listPrefix}[0].`;
1845
+ if (resultPath.startsWith(indexedPrefix)) {
1846
+ keys[target] = resultPath.slice(indexedPrefix.length);
1847
+ break;
1848
+ }
1849
+ const wildcardPrefix = `${listPrefix}[*].`;
1850
+ if (resultPath.startsWith(wildcardPrefix)) {
1851
+ keys[target] = resultPath.slice(wildcardPrefix.length);
1852
+ break;
1853
+ }
1854
+ const dottedIndexPrefix = `${listPrefix}.0.`;
1855
+ if (resultPath.startsWith(dottedIndexPrefix)) {
1856
+ keys[target] = resultPath.slice(dottedIndexPrefix.length);
1857
+ break;
1858
+ }
1859
+ }
1860
+ if (keys[target]) break;
1861
+ }
1862
+ }
1863
+ if (Object.keys(keys).length === 0 && input.rows[0]) {
1864
+ for (const key of Object.keys(input.rows[0])) {
1865
+ keys[key] = key;
1866
+ }
1867
+ }
1868
+ return keys;
1869
+ }
1870
+ function buildTargets(result, resultIdentityGetters) {
1871
+ const targets = {};
1872
+ const metadataTargets = new Set(Object.keys(resultIdentityGetters ?? {}));
1873
+ for (const target of metadataTargets) {
1874
+ const fromMetadata = findFirstTargetByPath(
1875
+ result,
1876
+ resultIdentityGetters?.[target]
1877
+ );
1878
+ if (fromMetadata) {
1879
+ targets[target] = fromMetadata;
1880
+ continue;
1881
+ }
1882
+ const fallback = findFirstTargetByKey(result, target);
1883
+ if (fallback) {
1884
+ targets[target] = fallback;
1885
+ }
1886
+ }
1887
+ if (metadataTargets.size > 0) return targets;
1888
+ for (const target of ["email", "phone", "linkedin", "domain", "status"]) {
1889
+ const found = findFirstTargetByKey(result, target);
1890
+ if (found) targets[target] = found;
1891
+ }
1892
+ return targets;
1893
+ }
1894
+ function buildLists(result, metadata) {
1895
+ const lists = {};
1896
+ const resolved = resolveListRows(result, metadata.listExtractorPaths);
1897
+ for (const [name, list] of Object.entries(resolved)) {
1898
+ lists[name] = {
1899
+ path: list.path,
1900
+ count: list.rows.length,
1901
+ keys: deriveListKeys({
1902
+ listPath: list.path,
1903
+ rows: list.rows,
1904
+ resultIdentityGetters: metadata.resultIdentityGetters,
1905
+ listIdentityGetters: metadata.listIdentityGetters
1906
+ })
1907
+ };
1908
+ }
1909
+ return lists;
1910
+ }
1911
+ function buildExtractedAccessors(targets) {
1912
+ return Object.fromEntries(
1913
+ Object.entries(targets).map(([target, metadata]) => {
1914
+ const accessor = { path: metadata.path };
1915
+ Object.defineProperties(accessor, {
1916
+ value: {
1917
+ value: metadata.value,
1918
+ enumerable: false
1919
+ },
1920
+ get: {
1921
+ value() {
1922
+ return metadata.value ?? null;
1923
+ },
1924
+ enumerable: false
1925
+ }
1926
+ });
1927
+ return [target, accessor];
1928
+ })
1929
+ );
1930
+ }
1931
+ function buildListAccessors(result, lists) {
1932
+ return Object.fromEntries(
1933
+ Object.entries(lists).map(([name, metadata]) => {
1934
+ const accessor = {
1935
+ path: metadata.path,
1936
+ count: metadata.count,
1937
+ keys: metadata.keys
1938
+ };
1939
+ Object.defineProperty(accessor, "get", {
1940
+ value() {
1941
+ return normalizeRows(getAtPath(result, metadata.path)) ?? [];
1942
+ },
1943
+ enumerable: false
1944
+ });
1945
+ return [name, accessor];
1946
+ })
1947
+ );
1948
+ }
1949
+ function createToolExecuteResult(input) {
1950
+ const result = toResultEnvelope(input.result);
1951
+ const resultRoot = {
1952
+ toolExecutionResult: {
1953
+ toolOutput: {
1954
+ raw: result.data,
1955
+ ...result.meta ? { meta: result.meta } : {}
1956
+ }
1957
+ }
1958
+ };
1959
+ const targets = buildTargets(
1960
+ resultRoot,
1961
+ input.metadata.resultIdentityGetters
1962
+ );
1963
+ const lists = buildLists(resultRoot, input.metadata);
1964
+ const metadata = {
1965
+ toolId: input.metadata.toolId,
1966
+ execution: input.execution,
1967
+ targets,
1968
+ lists
1969
+ };
1970
+ const wrapper = {
1971
+ status: input.status,
1972
+ toolOutput: {
1973
+ raw: result.data,
1974
+ ...result.meta ? { meta: result.meta } : {}
1975
+ },
1976
+ meta: input.execution,
1977
+ extractedValues: buildExtractedAccessors(targets),
1978
+ extractedLists: buildListAccessors(resultRoot, lists)
1979
+ };
1980
+ Object.defineProperty(wrapper, "_metadata", {
1981
+ value: metadata,
1982
+ enumerable: false
1983
+ });
1984
+ return wrapper;
1985
+ }
1986
+
1579
1987
  // src/play.ts
1580
1988
  var DeeplineConditionalStepResolver = class _DeeplineConditionalStepResolver {
1581
1989
  constructor(when2, run, elseValue) {
@@ -1712,10 +2120,10 @@ var DeeplineContext = class {
1712
2120
  *
1713
2121
  * @example
1714
2122
  * ```typescript
1715
- * const tools = await ctx.tools.list();
1716
- * const meta = await ctx.tools.get('apollo_people_search');
1717
- * const companyLookup = await ctx.tools.execute('test_company_search', { domain: 'stripe.com' });
1718
- * const company = companyLookup.result.data;
2123
+ * const tools = await deepline.tools.list();
2124
+ * const meta = await deepline.tools.get('apollo_people_search');
2125
+ * const companyLookup = await deepline.tools.execute('test_company_search', { domain: 'stripe.com' });
2126
+ * const company = companyLookup.toolOutput.raw;
1719
2127
  * ```
1720
2128
  */
1721
2129
  get tools() {
@@ -1725,11 +2133,14 @@ var DeeplineContext = class {
1725
2133
  /** Get detailed metadata for a tool. */
1726
2134
  get: (toolId) => this.client.getTool(toolId),
1727
2135
  /** Execute a tool and return the standard execution envelope. */
1728
- execute: async (toolId, input) => this.client.executeTool(
1729
- toolId,
1730
- input,
1731
- { includeToolMetadata: true }
1732
- )
2136
+ execute: async (toolId, input) => {
2137
+ const response = await this.client.executeTool(
2138
+ toolId,
2139
+ input,
2140
+ { includeToolMetadata: true }
2141
+ );
2142
+ return toolExecutionEnvelopeToResult(toolId, response);
2143
+ }
1733
2144
  };
1734
2145
  }
1735
2146
  get plays() {
@@ -1824,6 +2235,47 @@ var Deepline = class {
1824
2235
  return new DeeplineContext(options);
1825
2236
  }
1826
2237
  };
2238
+ function isRecord3(value) {
2239
+ return Boolean(value) && typeof value === "object" && !Array.isArray(value);
2240
+ }
2241
+ function stringArrayRecord(value) {
2242
+ if (!isRecord3(value)) return {};
2243
+ return Object.fromEntries(
2244
+ Object.entries(value).map(([key, paths]) => [
2245
+ key,
2246
+ Array.isArray(paths) ? paths.map(String) : []
2247
+ ])
2248
+ );
2249
+ }
2250
+ function stringArray(value) {
2251
+ return Array.isArray(value) ? value.map(String) : [];
2252
+ }
2253
+ function toolExecutionEnvelopeToResult(fallbackToolId, response) {
2254
+ const raw = response.toolExecutionResult?.toolOutput?.raw ?? null;
2255
+ const meta = response.toolExecutionResult?.toolOutput?.meta;
2256
+ const metadata = isRecord3(response._metadata) ? response._metadata.tool : null;
2257
+ const toolMetadata = isRecord3(metadata) ? metadata : {};
2258
+ return createToolExecuteResult({
2259
+ status: typeof response.status === "string" ? response.status : "completed",
2260
+ result: {
2261
+ data: raw,
2262
+ ...isRecord3(meta) ? { meta } : {}
2263
+ },
2264
+ metadata: {
2265
+ toolId: typeof toolMetadata.toolId === "string" ? toolMetadata.toolId : fallbackToolId,
2266
+ resultIdentityGetters: stringArrayRecord(
2267
+ toolMetadata.resultIdentityGetters
2268
+ ),
2269
+ listExtractorPaths: stringArray(toolMetadata.listExtractorPaths),
2270
+ listIdentityGetters: stringArrayRecord(toolMetadata.listIdentityGetters)
2271
+ },
2272
+ execution: {
2273
+ idempotent: true,
2274
+ cached: false,
2275
+ source: "live"
2276
+ }
2277
+ });
2278
+ }
1827
2279
  function defineInput(schema) {
1828
2280
  if (!schema || typeof schema !== "object" || Array.isArray(schema)) {
1829
2281
  throw new Error(
@@ -1950,7 +2402,7 @@ function getByDottedPath(root, dottedPath) {
1950
2402
  }
1951
2403
  return current;
1952
2404
  }
1953
- function normalizeRows(value) {
2405
+ function normalizeRows2(value) {
1954
2406
  if (!Array.isArray(value)) return null;
1955
2407
  return value.map((entry) => {
1956
2408
  if (isPlainObject(entry)) return entry;
@@ -1959,6 +2411,25 @@ function normalizeRows(value) {
1959
2411
  }
1960
2412
  function candidateRoots(payload) {
1961
2413
  const roots = [{ path: null, value: payload }];
2414
+ if (isPlainObject(payload) && isPlainObject(payload.toolExecutionResult)) {
2415
+ roots.push({ path: "toolExecutionResult", value: payload.toolExecutionResult });
2416
+ const toolOutput = payload.toolExecutionResult.toolOutput;
2417
+ if (isPlainObject(toolOutput)) {
2418
+ roots.push({ path: "toolExecutionResult.toolOutput", value: toolOutput });
2419
+ if (Object.prototype.hasOwnProperty.call(toolOutput, "raw")) {
2420
+ roots.push({
2421
+ path: "toolExecutionResult.toolOutput.raw",
2422
+ value: toolOutput.raw
2423
+ });
2424
+ }
2425
+ }
2426
+ }
2427
+ if (isPlainObject(payload) && isPlainObject(payload.output)) {
2428
+ roots.push({ path: "output", value: payload.output });
2429
+ if (Object.prototype.hasOwnProperty.call(payload.output, "body")) {
2430
+ roots.push({ path: "output.body", value: payload.output.body });
2431
+ }
2432
+ }
1962
2433
  if (isPlainObject(payload) && isPlainObject(payload.result)) {
1963
2434
  roots.push({ path: "result", value: payload.result });
1964
2435
  if (isPlainObject(payload.result.data)) {
@@ -1969,7 +2440,7 @@ function candidateRoots(payload) {
1969
2440
  }
1970
2441
  function findBestArrayCandidate(value, pathPrefix = "", depth = 0) {
1971
2442
  if (depth > 5) return null;
1972
- const directRows = normalizeRows(value);
2443
+ const directRows = normalizeRows2(value);
1973
2444
  const hasObjectRow = directRows?.some((row) => Object.keys(row).some((key) => key !== "value")) ?? false;
1974
2445
  let best = directRows && directRows.length > 0 && hasObjectRow ? { path: pathPrefix, rows: directRows } : null;
1975
2446
  if (!isPlainObject(value)) {
@@ -1991,7 +2462,7 @@ function tryConvertToList(payload, options) {
1991
2462
  for (const root of candidateRoots(payload)) {
1992
2463
  for (const extractorPath of listExtractorPaths) {
1993
2464
  const resolved = getByDottedPath(root.value, extractorPath);
1994
- const rows = normalizeRows(resolved);
2465
+ const rows = normalizeRows2(resolved);
1995
2466
  if (rows && rows.length > 0) {
1996
2467
  const sourcePath = root.path ? `${root.path}.${extractorPath}` : extractorPath;
1997
2468
  return { rows, strategy: "configured_paths", sourcePath };