@easynet/agent-tool 1.0.45 → 1.0.47

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 (40) hide show
  1. package/README.md +31 -105
  2. package/dist/api/extension/groupPrefix.d.ts.map +1 -1
  3. package/dist/api/main.cjs +19 -20
  4. package/dist/api/main.js +2 -3
  5. package/dist/api/runtimeFromConfig.d.ts.map +1 -1
  6. package/dist/{chunk-JH6TWGP4.js → chunk-2ZPDD7ZO.js} +722 -279
  7. package/dist/chunk-2ZPDD7ZO.js.map +1 -0
  8. package/dist/{chunk-ONXFQ6K5.js → chunk-64ZQQV5C.js} +79 -75
  9. package/dist/chunk-64ZQQV5C.js.map +1 -0
  10. package/dist/{chunk-YVL3UMM2.cjs → chunk-A5B6Q6EG.cjs} +733 -317
  11. package/dist/chunk-A5B6Q6EG.cjs.map +1 -0
  12. package/dist/{chunk-5WY557HJ.cjs → chunk-IAEVDXWS.cjs} +15 -16
  13. package/dist/chunk-IAEVDXWS.cjs.map +1 -0
  14. package/dist/{chunk-YUA6KJWF.js → chunk-KYBIKD5R.js} +5 -5
  15. package/dist/chunk-KYBIKD5R.js.map +1 -0
  16. package/dist/{chunk-ETXVT6FE.cjs → chunk-MDPU7EIO.cjs} +83 -87
  17. package/dist/chunk-MDPU7EIO.cjs.map +1 -0
  18. package/dist/index.cjs +195 -413
  19. package/dist/index.cjs.map +1 -1
  20. package/dist/index.d.ts +16 -63
  21. package/dist/index.d.ts.map +1 -1
  22. package/dist/index.js +171 -281
  23. package/dist/index.js.map +1 -1
  24. package/dist/utils/cli/index.cjs +16 -17
  25. package/dist/utils/cli/index.cjs.map +1 -1
  26. package/dist/utils/cli/index.js +3 -4
  27. package/dist/utils/cli/index.js.map +1 -1
  28. package/dist/utils/npmCache.d.ts +1 -1
  29. package/dist/utils/npmCache.d.ts.map +1 -1
  30. package/package.json +1 -1
  31. package/dist/chunk-5WY557HJ.cjs.map +0 -1
  32. package/dist/chunk-CLJCCBXA.js +0 -474
  33. package/dist/chunk-CLJCCBXA.js.map +0 -1
  34. package/dist/chunk-ETXVT6FE.cjs.map +0 -1
  35. package/dist/chunk-H5SPD2O7.cjs +0 -480
  36. package/dist/chunk-H5SPD2O7.cjs.map +0 -1
  37. package/dist/chunk-JH6TWGP4.js.map +0 -1
  38. package/dist/chunk-ONXFQ6K5.js.map +0 -1
  39. package/dist/chunk-YUA6KJWF.js.map +0 -1
  40. package/dist/chunk-YVL3UMM2.cjs.map +0 -1
@@ -1,18 +1,243 @@
1
1
  import { ToolRegistry, createTaggedError, withRetry } from './chunk-ZRHPGW7W.js';
2
2
  import { normalizeToolName } from './chunk-KDB3MY2H.js';
3
+ import { enrichSpecWithCanonicalSchema } from './chunk-NTWOVFEY.js';
4
+ import { readFileSync, existsSync, statSync } from 'fs';
5
+ import { resolve, dirname, join, normalize, basename, isAbsolute } from 'path';
6
+ import { parseYamlContent, resolveConfigPath } from '@easynet/agent-common';
3
7
  import Ajv from 'ajv';
4
8
  import addFormats from 'ajv-formats';
5
9
  import { bulkhead, circuitBreaker, handleAll, ConsecutiveBreaker } from 'cockatiel';
6
10
  import { EventEmitter } from 'eventemitter3';
7
11
  import { v4 } from 'uuid';
8
12
  import pTimeout from 'p-timeout';
9
- import { resolve, normalize, dirname, basename, join, isAbsolute } from 'path';
10
13
  import { realpath, access } from 'fs/promises';
11
- import { readFileSync, existsSync, statSync } from 'fs';
12
- import { parseYamlContent, resolveConfigPath, resolveLatestVersionFromRegistry, ensurePackageInCache, getPackageEntryPath, importFromCache } from '@easynet/agent-common';
13
- export { ensurePackageInCache, getPackageEntryPath, importFromCache, resolveLatestVersionFromRegistry } from '@easynet/agent-common';
14
14
  import { createRequire } from 'module';
15
+ import { resolveLatestVersionFromRegistry, ensurePackageInCache, getPackageEntryPath, importFromCache } from '@easynet/agent-common/npm';
16
+ import { createServer } from 'http';
17
+
18
+ function loadToolConfig(toolYamlPath) {
19
+ const abs = resolve(toolYamlPath);
20
+ const raw = readFileSync(abs, "utf8");
21
+ const parsed = parseYamlContent(raw, {
22
+ substituteEnv: false
23
+ });
24
+ if (!parsed || typeof parsed !== "object") return {};
25
+ const toolsBlock = parsed.tools;
26
+ if (toolsBlock != null && typeof toolsBlock === "object" && !Array.isArray(toolsBlock)) {
27
+ const toolDefaults = toolsBlock.defaults != null && typeof toolsBlock.defaults === "object" && !Array.isArray(toolsBlock.defaults) ? toolsBlock.defaults : void 0;
28
+ const packageToolDefaults2 = toolsBlock.packages != null && typeof toolsBlock.packages === "object" && !Array.isArray(toolsBlock.packages) ? toolsBlock.packages : void 0;
29
+ const list2 = Array.isArray(toolsBlock.list) && toolsBlock.list.length > 0 ? toolsBlock.list : void 0;
30
+ return {
31
+ tools: list2 ?? (packageToolDefaults2 ? Object.keys(packageToolDefaults2) : void 0),
32
+ sandboxedPath: typeof toolsBlock.sandboxedPath === "string" ? toolsBlock.sandboxedPath : parsed.sandboxedPath,
33
+ enableSandboxValidation: typeof toolsBlock.enableSandboxValidation === "boolean" ? toolsBlock.enableSandboxValidation : parsed.enableSandboxValidation,
34
+ allowedHosts: Array.isArray(toolsBlock.allowedHosts) ? toolsBlock.allowedHosts : parsed.allowedHosts,
35
+ blockedHosts: Array.isArray(toolsBlock.blockedHosts) ? toolsBlock.blockedHosts : parsed.blockedHosts,
36
+ blockedCidrs: Array.isArray(toolsBlock.blockedCidrs) ? toolsBlock.blockedCidrs : parsed.blockedCidrs,
37
+ toolDefaults,
38
+ packageToolDefaults: packageToolDefaults2
39
+ };
40
+ }
41
+ const packageToolDefaults = typeof parsed.packageToolDefaults === "object" && !Array.isArray(parsed.packageToolDefaults) ? parsed.packageToolDefaults : void 0;
42
+ const list = Array.isArray(parsed.tools) && parsed.tools.length > 0 ? parsed.tools : void 0;
43
+ return {
44
+ tools: list ?? (packageToolDefaults ? Object.keys(packageToolDefaults) : void 0),
45
+ sandboxedPath: parsed.sandboxedPath,
46
+ enableSandboxValidation: typeof parsed.enableSandboxValidation === "boolean" ? parsed.enableSandboxValidation : void 0,
47
+ allowedHosts: Array.isArray(parsed.allowedHosts) ? parsed.allowedHosts : void 0,
48
+ blockedHosts: Array.isArray(parsed.blockedHosts) ? parsed.blockedHosts : void 0,
49
+ blockedCidrs: Array.isArray(parsed.blockedCidrs) ? parsed.blockedCidrs : void 0,
50
+ toolDefaults: typeof parsed.toolDefaults === "object" && !Array.isArray(parsed.toolDefaults) ? parsed.toolDefaults : void 0,
51
+ packageToolDefaults
52
+ };
53
+ }
54
+ function resolveSandboxedPath(toolYamlPath, sandboxedPath) {
55
+ const configDir = dirname(resolve(toolYamlPath));
56
+ return resolveConfigPath(sandboxedPath, configDir, {
57
+ expandHome: true
58
+ });
59
+ }
60
+ var CACHE_SUBDIR = ".agent/cache";
61
+ function getCacheBaseFromToolConfig(toolYamlPath) {
62
+ const config = loadToolConfig(toolYamlPath);
63
+ if (!config.sandboxedPath || typeof config.sandboxedPath !== "string") return void 0;
64
+ const sandboxRoot = resolveSandboxedPath(toolYamlPath, config.sandboxedPath);
65
+ return join(sandboxRoot, CACHE_SUBDIR);
66
+ }
67
+ function findAndLoadToolConfig(dir) {
68
+ const resolvedDir = resolve(dir);
69
+ const candidates = [join(resolvedDir, "tool.yaml"), join(resolvedDir, ".tool.yaml")];
70
+ for (const p of candidates) {
71
+ if (existsSync(p)) {
72
+ const config = loadToolConfig(p);
73
+ return { ...config, configPath: p };
74
+ }
75
+ }
76
+ return {};
77
+ }
15
78
 
79
+ // src/tools/util/toolDescriptor.ts
80
+ var TOOL_PATH_REGEX = /^([a-z][a-z0-9-]*):([^/]+)\/([^#]+)(#(.+))?$/;
81
+ function isToolPath(descriptor) {
82
+ return TOOL_PATH_REGEX.test(descriptor.trim());
83
+ }
84
+ function isBarePackageDescriptor(descriptor) {
85
+ const parsed = parseToolPath(descriptor.trim());
86
+ return parsed !== null && parsed.toolName === "";
87
+ }
88
+ function parseToolPath(descriptor) {
89
+ const s = descriptor.trim();
90
+ const m = s.match(TOOL_PATH_REGEX);
91
+ if (!m || m[1] === void 0 || m[2] === void 0 || m[3] === void 0) return null;
92
+ return {
93
+ protocol: m[1],
94
+ scope: m[2],
95
+ packageWithVersion: m[3],
96
+ toolName: m[5] ?? ""
97
+ };
98
+ }
99
+ function npmDescriptorToRegistryPrefix(descriptor, resolvedVersion) {
100
+ const s = descriptor.trim();
101
+ if (typeof s !== "string" || !s.startsWith("npm:")) return "";
102
+ const rest = s.slice(4).trim();
103
+ const hashIdx = rest.indexOf("#");
104
+ const beforeHash = hashIdx < 0 ? rest : rest.slice(0, hashIdx);
105
+ const lastAt = beforeHash.lastIndexOf("@");
106
+ const scopeAndPackage = lastAt <= 0 ? beforeHash : beforeHash.slice(0, lastAt);
107
+ let version = lastAt <= 0 ? "latest" : beforeHash.slice(lastAt + 1).trim() || "latest";
108
+ if (version === "latest" || !version) {
109
+ const resolved = (resolvedVersion ?? "").trim();
110
+ if (resolved !== "" && resolved.toLowerCase() !== "latest") {
111
+ version = resolved;
112
+ } else {
113
+ throw new Error(
114
+ `Registry prefix requires a concrete version when descriptor uses latest (${descriptor}). Resolve version from registry (e.g. resolveLatestVersionFromRegistry) and pass as resolvedVersion.`
115
+ );
116
+ }
117
+ }
118
+ if (!version || version.toLowerCase() === "latest") {
119
+ throw new Error(
120
+ `Registry never uses "latest"; pass resolved concrete version for npm descriptor: ${descriptor}`
121
+ );
122
+ }
123
+ const slashIdx = scopeAndPackage.indexOf("/");
124
+ const scope = slashIdx < 0 ? scopeAndPackage : scopeAndPackage.slice(0, slashIdx).replace(/^@/, "");
125
+ const pkg = slashIdx < 0 ? "" : scopeAndPackage.slice(slashIdx + 1);
126
+ const segment = [scope, pkg, version].filter(Boolean).join(".");
127
+ const normalized = normalizeToolName(segment);
128
+ if (!normalized) return "";
129
+ return "npm." + normalized + ".";
130
+ }
131
+ function npmDescriptorToPackagePrefix(descriptor) {
132
+ const s = descriptor.trim();
133
+ if (typeof s !== "string" || !s.startsWith("npm:")) return "";
134
+ const rest = s.slice(4).trim();
135
+ const hashIdx = rest.indexOf("#");
136
+ const beforeHash = hashIdx < 0 ? rest : rest.slice(0, hashIdx);
137
+ const lastAt = beforeHash.lastIndexOf("@");
138
+ const scopeAndPackage = lastAt <= 0 ? beforeHash : beforeHash.slice(0, lastAt);
139
+ const slashIdx = scopeAndPackage.indexOf("/");
140
+ const scope = slashIdx < 0 ? scopeAndPackage : scopeAndPackage.slice(0, slashIdx).replace(/^@/, "");
141
+ const pkg = slashIdx < 0 ? "" : scopeAndPackage.slice(slashIdx + 1);
142
+ const segment = [scope, pkg].filter(Boolean).join(".");
143
+ const normalized = normalizeToolName(segment);
144
+ if (!normalized) return "";
145
+ return "npm." + normalized;
146
+ }
147
+ function npmDescriptorToPackagePrefixWithVersion(descriptor) {
148
+ const s = descriptor.trim();
149
+ if (typeof s !== "string" || !s.startsWith("npm:")) return "";
150
+ const rest = s.slice(4).trim();
151
+ const hashIdx = rest.indexOf("#");
152
+ const beforeHash = hashIdx < 0 ? rest : rest.slice(0, hashIdx);
153
+ const lastAt = beforeHash.lastIndexOf("@");
154
+ const scopeAndPackage = lastAt <= 0 ? beforeHash : beforeHash.slice(0, lastAt);
155
+ const version = lastAt <= 0 ? "" : beforeHash.slice(lastAt + 1).trim();
156
+ const slashIdx = scopeAndPackage.indexOf("/");
157
+ const scope = slashIdx < 0 ? scopeAndPackage : scopeAndPackage.slice(0, slashIdx).replace(/^@/, "");
158
+ const pkg = slashIdx < 0 ? "" : scopeAndPackage.slice(slashIdx + 1);
159
+ const segment = [scope, pkg, version].filter(Boolean).join(".");
160
+ const normalized = normalizeToolName(segment);
161
+ if (!normalized) return "";
162
+ return "npm." + normalized;
163
+ }
164
+ function getDisplayScope(registryName, _kind, _toolVersion) {
165
+ const i = registryName.indexOf(".");
166
+ return i < 0 ? registryName : registryName.slice(0, i);
167
+ }
168
+ function expandToolDescriptorsToRegistryNames(descriptors, registryNames) {
169
+ const out = [];
170
+ const seen = /* @__PURE__ */ new Set();
171
+ function add(name) {
172
+ const key = normalizeToolName(name);
173
+ if (registryNames.includes(key) && !seen.has(key)) {
174
+ seen.add(key);
175
+ out.push(key);
176
+ return;
177
+ }
178
+ const matched = registryNames.filter((r) => r === key || r.endsWith("." + key));
179
+ for (const m of matched) {
180
+ if (!seen.has(m)) {
181
+ seen.add(m);
182
+ out.push(m);
183
+ }
184
+ }
185
+ }
186
+ for (const d of descriptors) {
187
+ const s = d.trim();
188
+ if (!s) continue;
189
+ if (isToolPath(s)) {
190
+ if (registryNames.includes(s) && !seen.has(s)) {
191
+ seen.add(s);
192
+ out.push(s);
193
+ continue;
194
+ }
195
+ const path = parseToolPath(s);
196
+ if (path) {
197
+ const packagePrefix = path.protocol === "npm" ? npmDescriptorToPackagePrefix(s) : path.protocol === "file" ? fileDescriptorToPackagePrefix(s) : "";
198
+ const prefixWithDot = packagePrefix ? packagePrefix + "." : "";
199
+ if (prefixWithDot) {
200
+ if (path.toolName) {
201
+ const suffix = "." + path.toolName;
202
+ for (const r of registryNames) {
203
+ if (r.startsWith(prefixWithDot) && r.endsWith(suffix) && !seen.has(r)) {
204
+ seen.add(r);
205
+ out.push(r);
206
+ }
207
+ }
208
+ } else {
209
+ for (const r of registryNames) {
210
+ if (r.startsWith(prefixWithDot) && !seen.has(r)) {
211
+ seen.add(r);
212
+ out.push(r);
213
+ }
214
+ }
215
+ }
216
+ }
217
+ }
218
+ continue;
219
+ }
220
+ const name = normalizeToolName(s);
221
+ add(name);
222
+ }
223
+ return out;
224
+ }
225
+ function resolveToolDescriptor(descriptor) {
226
+ const s = descriptor.trim();
227
+ return s;
228
+ }
229
+ function fileDescriptorToPackagePrefix(descriptor) {
230
+ const path = parseToolPath(descriptor.trim());
231
+ if (!path || path.protocol !== "file") return "";
232
+ const pathPart = `${path.scope}/${path.packageWithVersion}`;
233
+ const normalized = normalizeToolName(pathPart);
234
+ if (!normalized) return "";
235
+ return "file." + normalized;
236
+ }
237
+ function fileDescriptorToRegistryPrefix(descriptor) {
238
+ const prefix = fileDescriptorToPackagePrefix(descriptor);
239
+ return prefix ? prefix + "." : "";
240
+ }
16
241
  var SchemaValidator = class {
17
242
  ajv;
18
243
  cache = /* @__PURE__ */ new Map();
@@ -1482,7 +1707,7 @@ var sandboxValidationEnabled = false;
1482
1707
  function setSandboxValidationEnabled(enabled) {
1483
1708
  sandboxValidationEnabled = enabled;
1484
1709
  }
1485
- async function resolveSandboxedPath(inputPath, sandboxRoot) {
1710
+ async function resolveSandboxedPath2(inputPath, sandboxRoot) {
1486
1711
  let normalizedRoot;
1487
1712
  try {
1488
1713
  normalizedRoot = await realpath(resolve(sandboxRoot));
@@ -1520,278 +1745,30 @@ function isWithinRoot(path, root) {
1520
1745
  return normalizedPath === normalizedRoot || normalizedPath.startsWith(normalizedRoot + "/");
1521
1746
  }
1522
1747
 
1523
- // src/tools/util/toolDescriptor.ts
1524
- var TOOL_PATH_REGEX = /^([a-z][a-z0-9-]*):([^/]+)\/([^#]+)(#(.+))?$/;
1525
- function isToolPath(descriptor) {
1526
- return TOOL_PATH_REGEX.test(descriptor.trim());
1748
+ // src/api/runtimeFromConfig.ts
1749
+ var requireFromPackage = createRequire(import.meta.url);
1750
+ function getProjectRequire() {
1751
+ const cwd = process.cwd();
1752
+ if (existsSync(join(cwd, "package.json"))) return createRequire(join(cwd, "package.json"));
1753
+ if (existsSync(join(cwd, "tool.yaml"))) return createRequire(join(cwd, "tool.yaml"));
1754
+ return null;
1527
1755
  }
1528
- function isBarePackageDescriptor(descriptor) {
1529
- const parsed = parseToolPath(descriptor.trim());
1530
- return parsed !== null && parsed.toolName === "";
1531
- }
1532
- function parseToolPath(descriptor) {
1533
- const s = descriptor.trim();
1534
- const m = s.match(TOOL_PATH_REGEX);
1535
- if (!m || m[1] === void 0 || m[2] === void 0 || m[3] === void 0) return null;
1536
- return {
1537
- protocol: m[1],
1538
- scope: m[2],
1539
- packageWithVersion: m[3],
1540
- toolName: m[5] ?? ""
1541
- };
1542
- }
1543
- function npmDescriptorToRegistryPrefix(descriptor, resolvedVersion) {
1544
- const s = descriptor.trim();
1545
- if (typeof s !== "string" || !s.startsWith("npm:")) return "";
1546
- const rest = s.slice(4).trim();
1547
- const hashIdx = rest.indexOf("#");
1548
- const beforeHash = hashIdx < 0 ? rest : rest.slice(0, hashIdx);
1549
- const lastAt = beforeHash.lastIndexOf("@");
1550
- const scopeAndPackage = lastAt <= 0 ? beforeHash : beforeHash.slice(0, lastAt);
1551
- let version = lastAt <= 0 ? "latest" : beforeHash.slice(lastAt + 1).trim() || "latest";
1552
- if (version === "latest" || !version) {
1553
- const resolved = (resolvedVersion ?? "").trim();
1554
- if (resolved !== "" && resolved.toLowerCase() !== "latest") {
1555
- version = resolved;
1556
- } else {
1557
- throw new Error(
1558
- `Registry prefix requires a concrete version when descriptor uses latest (${descriptor}). Resolve version from registry (e.g. resolveLatestVersionFromRegistry) and pass as resolvedVersion.`
1559
- );
1560
- }
1561
- }
1562
- if (!version || version.toLowerCase() === "latest") {
1563
- throw new Error(
1564
- `Registry never uses "latest"; pass resolved concrete version for npm descriptor: ${descriptor}`
1565
- );
1566
- }
1567
- const slashIdx = scopeAndPackage.indexOf("/");
1568
- const scope = slashIdx < 0 ? scopeAndPackage : scopeAndPackage.slice(0, slashIdx).replace(/^@/, "");
1569
- const pkg = slashIdx < 0 ? "" : scopeAndPackage.slice(slashIdx + 1);
1570
- const segment = [scope, pkg, version].filter(Boolean).join(".");
1571
- const normalized = normalizeToolName(segment);
1572
- if (!normalized) return "";
1573
- return "npm." + normalized + ".";
1574
- }
1575
- function npmDescriptorToPackagePrefix(descriptor) {
1576
- const s = descriptor.trim();
1577
- if (typeof s !== "string" || !s.startsWith("npm:")) return "";
1578
- const rest = s.slice(4).trim();
1579
- const hashIdx = rest.indexOf("#");
1580
- const beforeHash = hashIdx < 0 ? rest : rest.slice(0, hashIdx);
1581
- const lastAt = beforeHash.lastIndexOf("@");
1582
- const scopeAndPackage = lastAt <= 0 ? beforeHash : beforeHash.slice(0, lastAt);
1583
- const slashIdx = scopeAndPackage.indexOf("/");
1584
- const scope = slashIdx < 0 ? scopeAndPackage : scopeAndPackage.slice(0, slashIdx).replace(/^@/, "");
1585
- const pkg = slashIdx < 0 ? "" : scopeAndPackage.slice(slashIdx + 1);
1586
- const segment = [scope, pkg].filter(Boolean).join(".");
1587
- const normalized = normalizeToolName(segment);
1588
- if (!normalized) return "";
1589
- return "npm." + normalized;
1590
- }
1591
- function npmDescriptorToPackagePrefixWithVersion(descriptor) {
1592
- const s = descriptor.trim();
1593
- if (typeof s !== "string" || !s.startsWith("npm:")) return "";
1594
- const rest = s.slice(4).trim();
1595
- const hashIdx = rest.indexOf("#");
1596
- const beforeHash = hashIdx < 0 ? rest : rest.slice(0, hashIdx);
1597
- const lastAt = beforeHash.lastIndexOf("@");
1598
- const scopeAndPackage = lastAt <= 0 ? beforeHash : beforeHash.slice(0, lastAt);
1599
- const version = lastAt <= 0 ? "" : beforeHash.slice(lastAt + 1).trim();
1600
- const slashIdx = scopeAndPackage.indexOf("/");
1601
- const scope = slashIdx < 0 ? scopeAndPackage : scopeAndPackage.slice(0, slashIdx).replace(/^@/, "");
1602
- const pkg = slashIdx < 0 ? "" : scopeAndPackage.slice(slashIdx + 1);
1603
- const segment = [scope, pkg, version].filter(Boolean).join(".");
1604
- const normalized = normalizeToolName(segment);
1605
- if (!normalized) return "";
1606
- return "npm." + normalized;
1607
- }
1608
- function isNpmToolDescriptor(descriptor) {
1609
- return isToolPath(descriptor) && parseToolPath(descriptor)?.protocol === "npm";
1610
- }
1611
- function parseNpmToolDescriptor(descriptor) {
1612
- const parsed = parseToolPath(descriptor);
1613
- if (!parsed || parsed.protocol !== "npm") return null;
1614
- return {
1615
- fullPackage: `${parsed.scope}/${parsed.packageWithVersion}`,
1616
- toolPath: parsed.toolName
1617
- };
1618
- }
1619
- function getDisplayScope(registryName, _kind, _toolVersion) {
1620
- const i = registryName.indexOf(".");
1621
- return i < 0 ? registryName : registryName.slice(0, i);
1622
- }
1623
- function resolveNpmToolDescriptor(descriptor) {
1624
- return null;
1625
- }
1626
- function expandToolDescriptorsToRegistryNames(descriptors, registryNames) {
1627
- const out = [];
1628
- const seen = /* @__PURE__ */ new Set();
1629
- function add(name) {
1630
- const key = normalizeToolName(name);
1631
- if (registryNames.includes(key) && !seen.has(key)) {
1632
- seen.add(key);
1633
- out.push(key);
1634
- return;
1635
- }
1636
- const matched = registryNames.filter((r) => r === key || r.endsWith("." + key));
1637
- for (const m of matched) {
1638
- if (!seen.has(m)) {
1639
- seen.add(m);
1640
- out.push(m);
1641
- }
1642
- }
1643
- }
1644
- for (const d of descriptors) {
1645
- const s = d.trim();
1646
- if (!s) continue;
1647
- if (isToolPath(s)) {
1648
- if (registryNames.includes(s) && !seen.has(s)) {
1649
- seen.add(s);
1650
- out.push(s);
1651
- continue;
1652
- }
1653
- const path = parseToolPath(s);
1654
- if (path) {
1655
- const packagePrefix = path.protocol === "npm" ? npmDescriptorToPackagePrefix(s) : path.protocol === "file" ? fileDescriptorToPackagePrefix(s) : "";
1656
- const prefixWithDot = packagePrefix ? packagePrefix + "." : "";
1657
- if (prefixWithDot) {
1658
- if (path.toolName) {
1659
- const suffix = "." + path.toolName;
1660
- for (const r of registryNames) {
1661
- if (r.startsWith(prefixWithDot) && r.endsWith(suffix) && !seen.has(r)) {
1662
- seen.add(r);
1663
- out.push(r);
1664
- }
1665
- }
1666
- } else {
1667
- for (const r of registryNames) {
1668
- if (r.startsWith(prefixWithDot) && !seen.has(r)) {
1669
- seen.add(r);
1670
- out.push(r);
1671
- }
1672
- }
1673
- }
1674
- }
1675
- }
1676
- continue;
1677
- }
1678
- const name = normalizeToolName(s);
1679
- add(name);
1680
- }
1681
- return out;
1682
- }
1683
- function resolveToolDescriptor(descriptor) {
1684
- const s = descriptor.trim();
1685
- return s;
1686
- }
1687
- function normalizeToolList(descriptors) {
1688
- const seen = /* @__PURE__ */ new Set();
1689
- const out = [];
1690
- for (const d of descriptors) {
1691
- if (typeof d !== "string" || !d.trim()) continue;
1692
- const name = resolveToolDescriptor(d);
1693
- if (!seen.has(name)) {
1694
- seen.add(name);
1695
- out.push(name);
1696
- }
1697
- }
1698
- return out;
1699
- }
1700
- function fileDescriptorToPackagePrefix(descriptor) {
1701
- const path = parseToolPath(descriptor.trim());
1702
- if (!path || path.protocol !== "file") return "";
1703
- const pathPart = `${path.scope}/${path.packageWithVersion}`;
1704
- const normalized = normalizeToolName(pathPart);
1705
- if (!normalized) return "";
1706
- return "file." + normalized;
1707
- }
1708
- function fileDescriptorToRegistryPrefix(descriptor) {
1709
- const prefix = fileDescriptorToPackagePrefix(descriptor);
1710
- return prefix ? prefix + "." : "";
1711
- }
1712
- function loadToolConfig(toolYamlPath) {
1713
- const abs = resolve(toolYamlPath);
1714
- const raw = readFileSync(abs, "utf8");
1715
- const parsed = parseYamlContent(raw, {
1716
- substituteEnv: false
1717
- });
1718
- if (!parsed || typeof parsed !== "object") return {};
1719
- const toolsBlock = parsed.tools;
1720
- if (toolsBlock != null && typeof toolsBlock === "object" && !Array.isArray(toolsBlock)) {
1721
- const toolDefaults = toolsBlock.defaults != null && typeof toolsBlock.defaults === "object" && !Array.isArray(toolsBlock.defaults) ? toolsBlock.defaults : void 0;
1722
- const packageToolDefaults2 = toolsBlock.packages != null && typeof toolsBlock.packages === "object" && !Array.isArray(toolsBlock.packages) ? toolsBlock.packages : void 0;
1723
- const list2 = Array.isArray(toolsBlock.list) && toolsBlock.list.length > 0 ? toolsBlock.list : void 0;
1724
- return {
1725
- tools: list2 ?? (packageToolDefaults2 ? Object.keys(packageToolDefaults2) : void 0),
1726
- sandboxedPath: typeof toolsBlock.sandboxedPath === "string" ? toolsBlock.sandboxedPath : parsed.sandboxedPath,
1727
- enableSandboxValidation: typeof toolsBlock.enableSandboxValidation === "boolean" ? toolsBlock.enableSandboxValidation : parsed.enableSandboxValidation,
1728
- allowedHosts: Array.isArray(toolsBlock.allowedHosts) ? toolsBlock.allowedHosts : parsed.allowedHosts,
1729
- blockedHosts: Array.isArray(toolsBlock.blockedHosts) ? toolsBlock.blockedHosts : parsed.blockedHosts,
1730
- blockedCidrs: Array.isArray(toolsBlock.blockedCidrs) ? toolsBlock.blockedCidrs : parsed.blockedCidrs,
1731
- toolDefaults,
1732
- packageToolDefaults: packageToolDefaults2
1733
- };
1734
- }
1735
- const packageToolDefaults = typeof parsed.packageToolDefaults === "object" && !Array.isArray(parsed.packageToolDefaults) ? parsed.packageToolDefaults : void 0;
1736
- const list = Array.isArray(parsed.tools) && parsed.tools.length > 0 ? parsed.tools : void 0;
1737
- return {
1738
- tools: list ?? (packageToolDefaults ? Object.keys(packageToolDefaults) : void 0),
1739
- sandboxedPath: parsed.sandboxedPath,
1740
- enableSandboxValidation: typeof parsed.enableSandboxValidation === "boolean" ? parsed.enableSandboxValidation : void 0,
1741
- allowedHosts: Array.isArray(parsed.allowedHosts) ? parsed.allowedHosts : void 0,
1742
- blockedHosts: Array.isArray(parsed.blockedHosts) ? parsed.blockedHosts : void 0,
1743
- blockedCidrs: Array.isArray(parsed.blockedCidrs) ? parsed.blockedCidrs : void 0,
1744
- toolDefaults: typeof parsed.toolDefaults === "object" && !Array.isArray(parsed.toolDefaults) ? parsed.toolDefaults : void 0,
1745
- packageToolDefaults
1746
- };
1747
- }
1748
- function resolveSandboxedPath2(toolYamlPath, sandboxedPath) {
1749
- const configDir = dirname(resolve(toolYamlPath));
1750
- return resolveConfigPath(sandboxedPath, configDir, {
1751
- expandHome: true
1752
- });
1753
- }
1754
- var CACHE_SUBDIR = ".agent/cache";
1755
- function getCacheBaseFromToolConfig(toolYamlPath) {
1756
- const config = loadToolConfig(toolYamlPath);
1757
- if (!config.sandboxedPath || typeof config.sandboxedPath !== "string") return void 0;
1758
- const sandboxRoot = resolveSandboxedPath2(toolYamlPath, config.sandboxedPath);
1759
- return join(sandboxRoot, CACHE_SUBDIR);
1760
- }
1761
- function findAndLoadToolConfig(dir) {
1762
- const resolvedDir = resolve(dir);
1763
- const candidates = [join(resolvedDir, "tool.yaml"), join(resolvedDir, ".tool.yaml")];
1764
- for (const p of candidates) {
1765
- if (existsSync(p)) {
1766
- const config = loadToolConfig(p);
1767
- return { ...config, configPath: p };
1768
- }
1769
- }
1770
- return {};
1771
- }
1772
- var requireFromPackage = createRequire(import.meta.url);
1773
- function getProjectRequire() {
1774
- const cwd = process.cwd();
1775
- if (existsSync(join(cwd, "package.json"))) return createRequire(join(cwd, "package.json"));
1776
- if (existsSync(join(cwd, "tool.yaml"))) return createRequire(join(cwd, "tool.yaml"));
1777
- return null;
1778
- }
1779
- var DEFAULT_EXTENSION_PACKAGES = [];
1780
- function getInstalledPackageVersion(packageName) {
1781
- const projectRequire = getProjectRequire();
1782
- const requirers = [requireFromPackage];
1783
- if (projectRequire) requirers.push(projectRequire);
1784
- for (const req of requirers) {
1785
- try {
1786
- const pkgJsonPath = req.resolve(`${packageName}/package.json`);
1787
- const json = readFileSync(pkgJsonPath, "utf-8");
1788
- const pkg = JSON.parse(json);
1789
- return pkg.version ?? null;
1790
- } catch {
1791
- continue;
1792
- }
1793
- }
1794
- return null;
1756
+ var DEFAULT_EXTENSION_PACKAGES = [];
1757
+ function getInstalledPackageVersion(packageName) {
1758
+ const projectRequire = getProjectRequire();
1759
+ const requirers = [requireFromPackage];
1760
+ if (projectRequire) requirers.push(projectRequire);
1761
+ for (const req of requirers) {
1762
+ try {
1763
+ const pkgJsonPath = req.resolve(`${packageName}/package.json`);
1764
+ const json = readFileSync(pkgJsonPath, "utf-8");
1765
+ const pkg = JSON.parse(json);
1766
+ return pkg.version ?? null;
1767
+ } catch {
1768
+ continue;
1769
+ }
1770
+ }
1771
+ return null;
1795
1772
  }
1796
1773
  function getRegisterFn(mod) {
1797
1774
  return mod?.register ?? mod?.registerCoreTools;
@@ -2060,13 +2037,479 @@ async function createRuntimeFromConfig(options = {}) {
2060
2037
  return createRuntimeFromConfigSync(options);
2061
2038
  }
2062
2039
 
2040
+ // src/api/expose/openapi.ts
2041
+ function toolNameToSlug(name) {
2042
+ return name.replace(/\./g, "~");
2043
+ }
2044
+ function slugToToolName(slug) {
2045
+ return slug.replace(/~/g, ".");
2046
+ }
2047
+ function toolSchemaKey(name) {
2048
+ return `Tool_${name.replace(/[^a-zA-Z0-9_]/g, "_")}`;
2049
+ }
2050
+ var resultSchema = {
2051
+ type: "object",
2052
+ properties: {
2053
+ result: { description: "Tool return value", additionalProperties: true }
2054
+ }
2055
+ };
2056
+ var errorSchema = {
2057
+ type: "object",
2058
+ properties: {
2059
+ error: { type: "string" },
2060
+ kind: { type: "string" },
2061
+ details: { type: "object", additionalProperties: true }
2062
+ }
2063
+ };
2064
+ function toolsToOpenAPISpec(registry, options = {}) {
2065
+ const title = options.title ?? "Tool API";
2066
+ const version = options.version ?? "1.0.0";
2067
+ const basePath = (options.basePath ?? "").replace(/\/$/, "");
2068
+ const specs = registry.snapshot().map(enrichSpecWithCanonicalSchema);
2069
+ const toolNamesSchema = {
2070
+ type: "object",
2071
+ required: ["tools"],
2072
+ properties: {
2073
+ tools: {
2074
+ type: "array",
2075
+ items: {
2076
+ type: "object",
2077
+ properties: {
2078
+ name: { type: "string" },
2079
+ description: { type: "string" },
2080
+ kind: { type: "string" }
2081
+ }
2082
+ }
2083
+ }
2084
+ }
2085
+ };
2086
+ const invokeRequestBody = {
2087
+ type: "object",
2088
+ required: ["tool", "args"],
2089
+ properties: {
2090
+ tool: { type: "string", description: "Tool name (e.g. from GET /tools)" },
2091
+ args: {
2092
+ type: "object",
2093
+ description: "Tool arguments (schema per tool; use per-tool paths for typed schema)",
2094
+ additionalProperties: true
2095
+ }
2096
+ }
2097
+ };
2098
+ const prefix = basePath ? `${basePath}/` : "/";
2099
+ const paths = {
2100
+ [`${prefix}tools`]: {
2101
+ get: {
2102
+ summary: "List tools",
2103
+ description: "Returns all registered tool names and descriptions.",
2104
+ operationId: "listTools",
2105
+ responses: {
2106
+ "200": {
2107
+ description: "List of tools",
2108
+ content: {
2109
+ "application/json": {
2110
+ schema: toolNamesSchema
2111
+ }
2112
+ }
2113
+ }
2114
+ }
2115
+ }
2116
+ },
2117
+ [`${prefix}invoke`]: {
2118
+ post: {
2119
+ summary: "Invoke a tool (generic)",
2120
+ description: "Call any tool by name with body { tool, args }. For typed schemas use POST /invoke/{toolSlug}.",
2121
+ operationId: "invokeTool",
2122
+ requestBody: {
2123
+ required: true,
2124
+ content: {
2125
+ "application/json": {
2126
+ schema: invokeRequestBody
2127
+ }
2128
+ }
2129
+ },
2130
+ responses: {
2131
+ "200": {
2132
+ description: "Tool result",
2133
+ content: { "application/json": { schema: resultSchema } }
2134
+ },
2135
+ "400": {
2136
+ description: "Bad request",
2137
+ content: { "application/json": { schema: errorSchema } }
2138
+ }
2139
+ }
2140
+ }
2141
+ }
2142
+ };
2143
+ const schemaEntries = [];
2144
+ for (const s of specs) {
2145
+ const key = toolSchemaKey(s.name);
2146
+ schemaEntries.push([key, s.inputSchema]);
2147
+ const slug = toolNameToSlug(s.name);
2148
+ paths[`${prefix}invoke/${slug}`] = {
2149
+ post: {
2150
+ summary: s.description ?? s.name,
2151
+ description: `Invoke tool \`${s.name}\`. Request body is the tool's arguments (JSON Schema below).`,
2152
+ operationId: `invoke_${key}`,
2153
+ requestBody: {
2154
+ required: true,
2155
+ content: {
2156
+ "application/json": {
2157
+ schema: { $ref: `#/components/schemas/${key}` }
2158
+ }
2159
+ }
2160
+ },
2161
+ responses: {
2162
+ "200": {
2163
+ description: "Tool result",
2164
+ content: { "application/json": { schema: resultSchema } }
2165
+ },
2166
+ "400": {
2167
+ description: "Bad request (invalid args or tool error)",
2168
+ content: { "application/json": { schema: errorSchema } }
2169
+ }
2170
+ }
2171
+ }
2172
+ };
2173
+ }
2174
+ return {
2175
+ openapi: "3.0.3",
2176
+ info: { title, version },
2177
+ paths,
2178
+ components: {
2179
+ schemas: Object.fromEntries(schemaEntries)
2180
+ }
2181
+ };
2182
+ }
2183
+
2184
+ // src/api/expose/openapiHttp.ts
2185
+ var DEFAULT_CTX = {
2186
+ requestId: `http-${Date.now()}-${Math.random().toString(36).slice(2, 9)}`,
2187
+ taskId: `task-${Date.now()}`,
2188
+ permissions: [
2189
+ "read:web",
2190
+ "read:fs",
2191
+ "write:fs",
2192
+ "read:db",
2193
+ "write:db",
2194
+ "network",
2195
+ "workflow",
2196
+ "danger:destructive"
2197
+ ]
2198
+ };
2199
+ function parseBody(req) {
2200
+ return new Promise((resolve4, reject) => {
2201
+ const chunks = [];
2202
+ req.on("data", (chunk) => chunks.push(chunk));
2203
+ req.on("end", () => {
2204
+ const raw = Buffer.concat(chunks).toString("utf-8");
2205
+ if (!raw.trim()) {
2206
+ resolve4({});
2207
+ return;
2208
+ }
2209
+ try {
2210
+ resolve4(JSON.parse(raw));
2211
+ } catch {
2212
+ reject(new Error("Invalid JSON body"));
2213
+ }
2214
+ });
2215
+ req.on("error", reject);
2216
+ });
2217
+ }
2218
+ function sendJson(res, status, data) {
2219
+ res.writeHead(status, { "Content-Type": "application/json" });
2220
+ res.end(JSON.stringify(data));
2221
+ }
2222
+ function swaggerUiHtml(specUrl) {
2223
+ const specUrlEscaped = specUrl.replace(/"/g, "&quot;");
2224
+ return `<!DOCTYPE html>
2225
+ <html lang="en">
2226
+ <head>
2227
+ <meta charset="UTF-8">
2228
+ <meta name="viewport" content="width=device-width, initial-scale=1.0">
2229
+ <title>Tool API \u2013 Swagger UI</title>
2230
+ <link rel="stylesheet" href="https://unpkg.com/swagger-ui-dist@5/swagger-ui.css">
2231
+ </head>
2232
+ <body>
2233
+ <div id="swagger-ui"></div>
2234
+ <script src="https://unpkg.com/swagger-ui-dist@5/swagger-ui-bundle.js" crossorigin></script>
2235
+ <script src="https://unpkg.com/swagger-ui-dist@5/swagger-ui-standalone-preset.js" crossorigin></script>
2236
+ <script>
2237
+ window.onload = function() {
2238
+ window.ui = SwaggerUIBundle({
2239
+ url: "${specUrlEscaped}",
2240
+ dom_id: "#swagger-ui",
2241
+ deepLinking: true,
2242
+ presets: [
2243
+ SwaggerUIBundle.presets.apis,
2244
+ SwaggerUIStandalonePreset
2245
+ ],
2246
+ layout: "StandaloneLayout"
2247
+ });
2248
+ };
2249
+ </script>
2250
+ </body>
2251
+ </html>`;
2252
+ }
2253
+ function createOpenAPIHttpServer(runtime, options = {}) {
2254
+ const basePath = (options.basePath ?? "").replace(/\/$/, "");
2255
+ const ctxFactory = options.execContextFactory ?? (() => ({ ...DEFAULT_CTX }));
2256
+ const server = createServer(async (req, res) => {
2257
+ const url = req.url ?? "/";
2258
+ const path = url.split("?")[0] ?? "/";
2259
+ const norm = basePath ? path === basePath ? "" : path.replace(basePath, "") || "/" : path;
2260
+ try {
2261
+ if (req.method === "GET" && (norm === "/" || norm === "/swagger")) {
2262
+ const specPath = basePath ? `${basePath}/openapi.json` : "/openapi.json";
2263
+ const html = swaggerUiHtml(specPath);
2264
+ res.writeHead(200, { "Content-Type": "text/html; charset=utf-8" });
2265
+ res.end(html);
2266
+ return;
2267
+ }
2268
+ if (req.method === "GET" && (norm === "/openapi.json" || norm === "/spec")) {
2269
+ const spec = toolsToOpenAPISpec(runtime.getRegistry(), {
2270
+ title: "Tool API",
2271
+ version: "1.0.0",
2272
+ basePath: basePath || void 0
2273
+ });
2274
+ sendJson(res, 200, spec);
2275
+ return;
2276
+ }
2277
+ if (req.method === "GET" && norm === "/tools") {
2278
+ const { enrichSpecWithCanonicalSchema: enrichSpecWithCanonicalSchema2 } = await import('./canonicalCoreSchemas-PHGTNPN5.js');
2279
+ const specs = runtime.getRegistry().snapshot().map(enrichSpecWithCanonicalSchema2);
2280
+ const tools = specs.map((s) => ({
2281
+ name: s.name,
2282
+ description: s.description,
2283
+ kind: s.kind,
2284
+ inputSchema: s.inputSchema
2285
+ }));
2286
+ sendJson(res, 200, { tools });
2287
+ return;
2288
+ }
2289
+ if (req.method === "POST" && norm === "/invoke") {
2290
+ const body = await parseBody(req);
2291
+ const tool = body?.tool;
2292
+ const args = body?.args ?? {};
2293
+ if (typeof tool !== "string" || !tool.trim()) {
2294
+ sendJson(res, 400, { error: "Missing or invalid 'tool' in body", kind: "BAD_REQUEST" });
2295
+ return;
2296
+ }
2297
+ const ctx = ctxFactory(req);
2298
+ const result = await runtime.invoke(
2299
+ { tool: tool.trim(), args, purpose: "openapi" },
2300
+ ctx
2301
+ );
2302
+ if (result.ok) {
2303
+ sendJson(res, 200, { result: result.result });
2304
+ return;
2305
+ }
2306
+ sendJson(res, 400, {
2307
+ error: result.error?.message ?? "Tool failed",
2308
+ kind: result.error?.kind,
2309
+ details: result.error?.details
2310
+ });
2311
+ return;
2312
+ }
2313
+ if (req.method === "POST" && norm.startsWith("/invoke/") && norm.length > "/invoke/".length) {
2314
+ const slug = norm.slice("/invoke/".length);
2315
+ const toolName = slugToToolName(slug);
2316
+ let args;
2317
+ try {
2318
+ args = await parseBody(req);
2319
+ } catch {
2320
+ sendJson(res, 400, { error: "Invalid JSON body", kind: "BAD_REQUEST" });
2321
+ return;
2322
+ }
2323
+ const ctx = ctxFactory(req);
2324
+ const result = await runtime.invoke(
2325
+ { tool: toolName, args: args ?? {}, purpose: "openapi" },
2326
+ ctx
2327
+ );
2328
+ if (result.ok) {
2329
+ sendJson(res, 200, { result: result.result });
2330
+ return;
2331
+ }
2332
+ sendJson(res, 400, {
2333
+ error: result.error?.message ?? "Tool failed",
2334
+ kind: result.error?.kind,
2335
+ details: result.error?.details
2336
+ });
2337
+ return;
2338
+ }
2339
+ res.writeHead(404, { "Content-Type": "application/json" });
2340
+ res.end(JSON.stringify({ error: "Not found", path: norm }));
2341
+ } catch (err) {
2342
+ const message = err instanceof Error ? err.message : String(err);
2343
+ sendJson(res, 500, { error: message, kind: "INTERNAL_ERROR" });
2344
+ }
2345
+ });
2346
+ return server;
2347
+ }
2348
+ function listenOpenAPIHttpServer(server, options = {}) {
2349
+ return new Promise((resolve4, reject) => {
2350
+ const port = options.port ?? 0;
2351
+ const host = options.host ?? "localhost";
2352
+ server.listen(port, host, () => {
2353
+ const addr = server.address();
2354
+ const actualPort = typeof addr === "object" && addr?.port != null ? addr.port : port;
2355
+ resolve4({ port: actualPort, host });
2356
+ });
2357
+ server.on("error", reject);
2358
+ });
2359
+ }
2360
+ async function createHttpService(runtimeOrConfig, options = {}) {
2361
+ const runtime = "invoke" in runtimeOrConfig && typeof runtimeOrConfig.invoke === "function" ? runtimeOrConfig : (await createRuntimeFromConfig(runtimeOrConfig)).runtime;
2362
+ const server = createOpenAPIHttpServer(runtime, options);
2363
+ const openApiSpec = toolsToOpenAPISpec(runtime.getRegistry(), {
2364
+ title: options.title ?? "Tool API",
2365
+ version: options.version ?? "1.0.0",
2366
+ basePath: options.basePath
2367
+ });
2368
+ return {
2369
+ server,
2370
+ openApiSpec,
2371
+ listen: (listenOpts) => listenOpenAPIHttpServer(server, listenOpts)
2372
+ };
2373
+ }
2374
+
2063
2375
  // src/tools/mcp/types.ts
2064
2376
  var MCP_KIND = "mcp";
2065
2377
 
2378
+ // src/api/expose/mcpServer.ts
2379
+ var DEFAULT_CTX2 = {
2380
+ requestId: `mcp-${Date.now()}-${Math.random().toString(36).slice(2, 9)}`,
2381
+ taskId: `task-${Date.now()}`,
2382
+ permissions: [
2383
+ "read:web",
2384
+ "read:fs",
2385
+ "write:fs",
2386
+ "read:db",
2387
+ "write:db",
2388
+ "network",
2389
+ "workflow",
2390
+ "danger:destructive"
2391
+ ]
2392
+ };
2393
+ function toMcpToolName(registryName) {
2394
+ return normalizeToolName(registryName);
2395
+ }
2396
+ async function createMcpServerWithTools(runtime, options) {
2397
+ const { McpServer } = await import('@modelcontextprotocol/sdk/server/mcp.js');
2398
+ const name = options.name ?? "agent-tool";
2399
+ const version = options.version ?? "1.0.0";
2400
+ const ctxFactory = options.execContextFactory ?? (() => ({ ...DEFAULT_CTX2 }));
2401
+ const server = new McpServer({ name, version });
2402
+ const registry = runtime.getRegistry();
2403
+ const specs = registry.snapshot();
2404
+ for (const spec of specs) {
2405
+ const mcpName = toMcpToolName(spec.name);
2406
+ server.registerTool(
2407
+ mcpName,
2408
+ {
2409
+ description: spec.description ?? `Tool: ${spec.name}`,
2410
+ inputSchema: spec.inputSchema,
2411
+ _meta: spec._meta
2412
+ },
2413
+ async (args) => {
2414
+ const ctx = ctxFactory();
2415
+ const result = await runtime.invoke(
2416
+ { tool: spec.name, args: args ?? {}, purpose: MCP_KIND },
2417
+ ctx
2418
+ );
2419
+ if (result.ok) {
2420
+ return { content: [{ type: "text", text: JSON.stringify(result.result) }] };
2421
+ }
2422
+ const err = result.error;
2423
+ return {
2424
+ content: [
2425
+ {
2426
+ type: "text",
2427
+ text: JSON.stringify({ error: err?.message ?? "Tool failed", kind: err?.kind })
2428
+ }
2429
+ ],
2430
+ isError: true
2431
+ };
2432
+ }
2433
+ );
2434
+ }
2435
+ return { server };
2436
+ }
2437
+ async function createMCPServer(runtimeOrConfig, options = {}) {
2438
+ const runtime = "invoke" in runtimeOrConfig && typeof runtimeOrConfig.invoke === "function" ? runtimeOrConfig : (await createRuntimeFromConfig(runtimeOrConfig)).runtime;
2439
+ const { StdioServerTransport } = await import('@modelcontextprotocol/sdk/server/stdio.js');
2440
+ const { server } = await createMcpServerWithTools(runtime, options);
2441
+ return {
2442
+ server,
2443
+ async connectStdio() {
2444
+ const transport = new StdioServerTransport();
2445
+ await server.connect(transport);
2446
+ }
2447
+ };
2448
+ }
2449
+ function createMCPStreamableHttpHandler(runtimeOrConfig, options = {}) {
2450
+ if ("invoke" in runtimeOrConfig && typeof runtimeOrConfig.invoke === "function") {
2451
+ const runtime = runtimeOrConfig;
2452
+ return async function streamableHttpHandler(req, res, parsedBody) {
2453
+ const { StreamableHTTPServerTransport } = await import('@modelcontextprotocol/sdk/server/streamableHttp.js');
2454
+ const { server } = await createMcpServerWithTools(runtime, options);
2455
+ const transport = new StreamableHTTPServerTransport({ sessionIdGenerator: void 0 });
2456
+ await server.connect(transport);
2457
+ const onClose = () => {
2458
+ transport.close().catch(() => {
2459
+ });
2460
+ server.close().catch(() => {
2461
+ });
2462
+ res.removeListener("close", onClose);
2463
+ res.removeListener("finish", onClose);
2464
+ };
2465
+ res.once("close", onClose);
2466
+ res.once("finish", onClose);
2467
+ await transport.handleRequest(
2468
+ req,
2469
+ res,
2470
+ parsedBody
2471
+ );
2472
+ };
2473
+ }
2474
+ return (async () => {
2475
+ const { runtime } = await createRuntimeFromConfig(runtimeOrConfig);
2476
+ return createMCPStreamableHttpHandler(runtime, options);
2477
+ })();
2478
+ }
2479
+ async function createMCPServerStreamableHttp(runtimeOrConfig, options = {}) {
2480
+ const path = options.path ?? "/mcp";
2481
+ const host = options.host ?? "127.0.0.1";
2482
+ const port = options.port ?? 3e3;
2483
+ const { createMcpExpressApp } = await import('@modelcontextprotocol/sdk/server/express.js');
2484
+ const handler = "invoke" in runtimeOrConfig && typeof runtimeOrConfig.invoke === "function" ? createMCPStreamableHttpHandler(runtimeOrConfig, options) : await createMCPStreamableHttpHandler(runtimeOrConfig, options);
2485
+ const app = createMcpExpressApp({ host });
2486
+ app.post(path, handler);
2487
+ return {
2488
+ app,
2489
+ path,
2490
+ async listen(listenPort, listenHost) {
2491
+ const p = listenPort ?? port;
2492
+ const h = listenHost ?? host;
2493
+ return new Promise((resolve4, reject) => {
2494
+ const server = app.listen(p, h, () => {
2495
+ const addr = server.address();
2496
+ const actualPort = typeof addr === "object" && addr !== null && "port" in addr ? addr.port : p;
2497
+ resolve4({ url: `http://${h}:${actualPort}${path}`, port: actualPort });
2498
+ });
2499
+ });
2500
+ }
2501
+ };
2502
+ }
2503
+ async function runMCPServerOverStdio(runtime, options = {}) {
2504
+ const result = await createMCPServer(runtime, options);
2505
+ await result.connectStdio();
2506
+ return result;
2507
+ }
2508
+
2066
2509
  // src/tools/langchain/types.ts
2067
2510
  var LANGCHAIN_KIND = "langchain";
2068
2511
  var LANGCHAIN_DIR_NAME = "langchain";
2069
2512
 
2070
- export { BudgetManager, EventLog, LANGCHAIN_DIR_NAME, LANGCHAIN_KIND, MCP_KIND, Metrics, PTCRuntime, PolicyDeniedError, PolicyEngine, SchemaValidationError, SchemaValidator, Tracing, buildEvidence, createLogger, createRuntimeFromConfig, createRuntimeFromConfigSync, expandToolDescriptorsToRegistryNames, fileDescriptorToPackagePrefix, findAndLoadToolConfig, getDisplayScope, isBarePackageDescriptor, isNpmToolDescriptor, loadToolConfig, normalizeToolList, npmDescriptorToPackagePrefixWithVersion, npmDescriptorToRegistryPrefix, parseNpmToolDescriptor, resolveNpmToolDescriptor, resolveSandboxedPath, resolveSandboxedPath2, resolveToolDescriptor, sanitizeForLog, setSandboxValidationEnabled, summarizeForLog };
2071
- //# sourceMappingURL=chunk-JH6TWGP4.js.map
2072
- //# sourceMappingURL=chunk-JH6TWGP4.js.map
2513
+ export { LANGCHAIN_DIR_NAME, LANGCHAIN_KIND, MCP_KIND, PTCRuntime, createHttpService, createMCPServer, createMCPServerStreamableHttp, createMCPStreamableHttpHandler, createRuntimeFromConfig, createRuntimeFromConfigSync, expandToolDescriptorsToRegistryNames, fileDescriptorToPackagePrefix, findAndLoadToolConfig, getDisplayScope, isBarePackageDescriptor, loadToolConfig, npmDescriptorToPackagePrefixWithVersion, resolveSandboxedPath, resolveSandboxedPath2, resolveToolDescriptor, runMCPServerOverStdio, setSandboxValidationEnabled };
2514
+ //# sourceMappingURL=chunk-2ZPDD7ZO.js.map
2515
+ //# sourceMappingURL=chunk-2ZPDD7ZO.js.map