@frontmcp/plugin-codecall 1.8.4 → 1.8.6
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/esm/index.mjs +266 -35
- package/esm/package.json +7 -5
- package/index.js +266 -35
- package/package.json +7 -5
- package/services/enclave.service.d.ts +0 -1
- package/services/enclave.service.d.ts.map +1 -1
- package/tools/describe.tool.d.ts +3 -1
- package/tools/describe.tool.d.ts.map +1 -1
- package/tools/execute.schema.d.ts +2 -2
- package/tools/execute.schema.d.ts.map +1 -1
- package/utils/describe.utils.d.ts +11 -5
- package/utils/describe.utils.d.ts.map +1 -1
- package/utils/script-lines.d.ts +14 -0
- package/utils/script-lines.d.ts.map +1 -0
package/esm/index.mjs
CHANGED
|
@@ -1871,6 +1871,121 @@ function toSandboxToolNamespaces(namespaces, reservedGlobals = []) {
|
|
|
1871
1871
|
return count > 0 ? bindable : void 0;
|
|
1872
1872
|
}
|
|
1873
1873
|
|
|
1874
|
+
// plugins/plugin-codecall/src/utils/script-lines.ts
|
|
1875
|
+
import { isWrappedInMain, transformAgentScript } from "@enclave-vm/ast";
|
|
1876
|
+
import * as acorn from "acorn";
|
|
1877
|
+
var PARSE_OPTIONS = { ecmaVersion: "latest", locations: true };
|
|
1878
|
+
var NON_CHILD_KEYS = /* @__PURE__ */ new Set(["type", "loc", "start", "end", "range"]);
|
|
1879
|
+
function isNode(value) {
|
|
1880
|
+
return typeof value === "object" && value !== null && typeof value.type === "string";
|
|
1881
|
+
}
|
|
1882
|
+
function isAddedByTransform(node) {
|
|
1883
|
+
if (node.type === "VariableDeclaration") {
|
|
1884
|
+
const [declaration] = node["declarations"] ?? [];
|
|
1885
|
+
const id = declaration?.["id"];
|
|
1886
|
+
return typeof id?.["name"] === "string" && id["name"].startsWith("__iter_");
|
|
1887
|
+
}
|
|
1888
|
+
if (node.type === "IfStatement") {
|
|
1889
|
+
const right = node["test"]?.["right"];
|
|
1890
|
+
return right?.type === "Identifier" && right["name"] === "__maxIterations";
|
|
1891
|
+
}
|
|
1892
|
+
return false;
|
|
1893
|
+
}
|
|
1894
|
+
function parseScript(script) {
|
|
1895
|
+
try {
|
|
1896
|
+
return { body: parseBody(script, "script"), offset: 0 };
|
|
1897
|
+
} catch {
|
|
1898
|
+
try {
|
|
1899
|
+
return { body: parseBody(script, "module"), offset: 0 };
|
|
1900
|
+
} catch {
|
|
1901
|
+
const wrapped = parseBody(`async function __temp__() {
|
|
1902
|
+
${script}
|
|
1903
|
+
}`, "script");
|
|
1904
|
+
const fn = wrapped[0];
|
|
1905
|
+
const block = fn?.["body"];
|
|
1906
|
+
return { body: block?.["body"] ?? [], offset: 1 };
|
|
1907
|
+
}
|
|
1908
|
+
}
|
|
1909
|
+
}
|
|
1910
|
+
function parseBody(code, sourceType) {
|
|
1911
|
+
const program = acorn.parse(code, { ...PARSE_OPTIONS, sourceType });
|
|
1912
|
+
return program["body"] ?? [];
|
|
1913
|
+
}
|
|
1914
|
+
function treesOf(script) {
|
|
1915
|
+
try {
|
|
1916
|
+
const wrap = !isWrappedInMain(script);
|
|
1917
|
+
const printed = parseBody(transformAgentScript(script, { wrapInMain: wrap }), "script");
|
|
1918
|
+
const { body, offset } = parseScript(script);
|
|
1919
|
+
if (!wrap) return { printed, script: body, offset };
|
|
1920
|
+
const main = printed[0]?.["body"];
|
|
1921
|
+
return { printed: main?.["body"] ?? [], script: body, offset };
|
|
1922
|
+
} catch {
|
|
1923
|
+
return void 0;
|
|
1924
|
+
}
|
|
1925
|
+
}
|
|
1926
|
+
function pairLists(printed, script, depth, out, offset) {
|
|
1927
|
+
const kept = printed.filter((node) => !(isNode(node) && isAddedByTransform(node)));
|
|
1928
|
+
if (kept.length !== script.length) return;
|
|
1929
|
+
kept.forEach((node, index) => {
|
|
1930
|
+
const own = script[index];
|
|
1931
|
+
if (isNode(node) && isNode(own)) pairNodes(node, own, depth, out, offset);
|
|
1932
|
+
});
|
|
1933
|
+
}
|
|
1934
|
+
function pairNodes(printed, script, depth, out, offset) {
|
|
1935
|
+
if (printed.type === "ReturnStatement" && script.type === "ExpressionStatement") {
|
|
1936
|
+
record(printed, script, depth, out, offset);
|
|
1937
|
+
const argument = printed["argument"];
|
|
1938
|
+
const expression = script["expression"];
|
|
1939
|
+
if (isNode(argument) && isNode(expression)) pairNodes(argument, expression, depth + 1, out, offset);
|
|
1940
|
+
return;
|
|
1941
|
+
}
|
|
1942
|
+
if (printed.type !== script.type) return;
|
|
1943
|
+
record(printed, script, depth, out, offset);
|
|
1944
|
+
for (const key of Object.keys(printed)) {
|
|
1945
|
+
if (NON_CHILD_KEYS.has(key)) continue;
|
|
1946
|
+
const printedChild = printed[key];
|
|
1947
|
+
const scriptChild = script[key];
|
|
1948
|
+
if (Array.isArray(printedChild) && Array.isArray(scriptChild)) {
|
|
1949
|
+
pairLists(printedChild, scriptChild, depth + 1, out, offset);
|
|
1950
|
+
} else if (isNode(printedChild) && isNode(scriptChild)) {
|
|
1951
|
+
pairNodes(printedChild, scriptChild, depth + 1, out, offset);
|
|
1952
|
+
}
|
|
1953
|
+
}
|
|
1954
|
+
}
|
|
1955
|
+
function record(printed, script, depth, out, offset) {
|
|
1956
|
+
if (!printed.loc || !script.loc) return;
|
|
1957
|
+
out.push({
|
|
1958
|
+
printedStart: printed.loc.start.line,
|
|
1959
|
+
printedEnd: printed.loc.end.line,
|
|
1960
|
+
scriptLine: script.loc.start.line - offset,
|
|
1961
|
+
depth
|
|
1962
|
+
});
|
|
1963
|
+
}
|
|
1964
|
+
function validatedLineMapper(script) {
|
|
1965
|
+
const trees = treesOf(script);
|
|
1966
|
+
if (!trees) return () => void 0;
|
|
1967
|
+
const pairs = [];
|
|
1968
|
+
pairLists(trees.printed, trees.script, 0, pairs, trees.offset);
|
|
1969
|
+
return (printedLine) => {
|
|
1970
|
+
const starting = pairs.filter((pair) => pair.printedStart === printedLine);
|
|
1971
|
+
const candidates = starting.length > 0 ? starting : pairs.filter((pair) => pair.printedStart <= printedLine && printedLine <= pair.printedEnd);
|
|
1972
|
+
const best = candidates.reduce(
|
|
1973
|
+
(deepest, pair) => !deepest || pair.depth > deepest.depth ? pair : deepest,
|
|
1974
|
+
void 0
|
|
1975
|
+
);
|
|
1976
|
+
return best && best.scriptLine >= 1 ? best.scriptLine : void 0;
|
|
1977
|
+
};
|
|
1978
|
+
}
|
|
1979
|
+
var ISSUE_LINE_RE = / \(line (\d+)\)/g;
|
|
1980
|
+
function withScriptLines(message, script) {
|
|
1981
|
+
if (!message.includes("(line ")) return message;
|
|
1982
|
+
const lineOf = validatedLineMapper(script);
|
|
1983
|
+
return message.replace(ISSUE_LINE_RE, (_match, printed) => {
|
|
1984
|
+
const line = lineOf(Number(printed));
|
|
1985
|
+
return line === void 0 ? "" : ` (line ${line})`;
|
|
1986
|
+
});
|
|
1987
|
+
}
|
|
1988
|
+
|
|
1874
1989
|
// plugins/plugin-codecall/src/services/enclave.service.ts
|
|
1875
1990
|
function toolFailureMessage(error, toolName) {
|
|
1876
1991
|
if (typeof error === "string" && error) return error;
|
|
@@ -1995,7 +2110,7 @@ var EnclaveService = class {
|
|
|
1995
2110
|
const enclave = createEnclave(options);
|
|
1996
2111
|
try {
|
|
1997
2112
|
const result = await enclave.run(code);
|
|
1998
|
-
return this.mapEnclaveResult(result, logs, toolFailures);
|
|
2113
|
+
return this.mapEnclaveResult(result, logs, toolFailures, code);
|
|
1999
2114
|
} finally {
|
|
2000
2115
|
enclave.dispose();
|
|
2001
2116
|
}
|
|
@@ -2003,7 +2118,7 @@ var EnclaveService = class {
|
|
|
2003
2118
|
/**
|
|
2004
2119
|
* Map Enclave ExecutionResult to EnclaveExecutionResult
|
|
2005
2120
|
*/
|
|
2006
|
-
mapEnclaveResult(result, logs, toolFailures = []) {
|
|
2121
|
+
mapEnclaveResult(result, logs, toolFailures = [], script = "") {
|
|
2007
2122
|
const stats = {
|
|
2008
2123
|
duration: result.stats.duration,
|
|
2009
2124
|
toolCallCount: result.stats.toolCallCount,
|
|
@@ -2045,7 +2160,9 @@ var EnclaveService = class {
|
|
|
2045
2160
|
return {
|
|
2046
2161
|
success: false,
|
|
2047
2162
|
error: {
|
|
2048
|
-
|
|
2163
|
+
// The enclave names lines of the code it validated (the script wrapped and printed again),
|
|
2164
|
+
// not the script's own.
|
|
2165
|
+
message: withScriptLines(error.message, script),
|
|
2049
2166
|
name: "ValidationError",
|
|
2050
2167
|
code: error.code,
|
|
2051
2168
|
...blockedPatterns.length > 0 ? { blockedPatterns } : {}
|
|
@@ -2651,6 +2768,43 @@ function generateSampleParams(schema) {
|
|
|
2651
2768
|
}
|
|
2652
2769
|
return Object.keys(params).length > 0 ? params : null;
|
|
2653
2770
|
}
|
|
2771
|
+
function fitString(schema, value) {
|
|
2772
|
+
let fitted = value;
|
|
2773
|
+
if (schema.maxLength !== void 0 && fitted.length > schema.maxLength) {
|
|
2774
|
+
fitted = fitted.slice(0, Math.max(0, schema.maxLength));
|
|
2775
|
+
}
|
|
2776
|
+
if (schema.minLength !== void 0 && fitted.length < schema.minLength) {
|
|
2777
|
+
fitted = fitted.padEnd(schema.minLength, "x");
|
|
2778
|
+
}
|
|
2779
|
+
return fitted;
|
|
2780
|
+
}
|
|
2781
|
+
function isFreeTextString(schema) {
|
|
2782
|
+
return schema?.type === "string" && schema.enum === void 0 && schema.const === void 0 && schema.default === void 0 && schema.pattern === void 0 && schema.format === void 0;
|
|
2783
|
+
}
|
|
2784
|
+
function acceptsNumber(schema, value) {
|
|
2785
|
+
if (schema.const !== void 0) return schema.const === value;
|
|
2786
|
+
if (schema.enum !== void 0) return schema.enum.includes(value);
|
|
2787
|
+
if (schema.minimum !== void 0 && value < schema.minimum) return false;
|
|
2788
|
+
if (schema.maximum !== void 0 && value > schema.maximum) return false;
|
|
2789
|
+
return true;
|
|
2790
|
+
}
|
|
2791
|
+
function pickNumber(schema, preferred) {
|
|
2792
|
+
const accepted = preferred.find((value) => acceptsNumber(schema, value));
|
|
2793
|
+
if (accepted !== void 0) return accepted;
|
|
2794
|
+
const named = [schema.const, schema.enum?.[0], schema.minimum, schema.maximum].find(
|
|
2795
|
+
(value) => typeof value === "number" && acceptsNumber(schema, value)
|
|
2796
|
+
);
|
|
2797
|
+
return named;
|
|
2798
|
+
}
|
|
2799
|
+
function formatInlineArgs(args) {
|
|
2800
|
+
const entries = Object.entries(args).map(([key, value]) => {
|
|
2801
|
+
const name = /^[A-Za-z_$][\w$]*$/.test(key) ? key : JSON.stringify(key);
|
|
2802
|
+
const plain = typeof value === "string" && [...value].every((ch) => ch !== "'" && ch !== "\\" && ch >= " ");
|
|
2803
|
+
const literal = plain ? `'${value}'` : JSON.stringify(value);
|
|
2804
|
+
return `${name}: ${literal}`;
|
|
2805
|
+
});
|
|
2806
|
+
return entries.length > 0 ? `{ ${entries.join(", ")} }` : "{}";
|
|
2807
|
+
}
|
|
2654
2808
|
function getSampleValue(schema, key) {
|
|
2655
2809
|
if (schema.default !== void 0) {
|
|
2656
2810
|
return schema.default;
|
|
@@ -2664,11 +2818,11 @@ function getSampleValue(schema, key) {
|
|
|
2664
2818
|
const type = Array.isArray(schema.type) ? schema.type[0] : schema.type;
|
|
2665
2819
|
switch (type) {
|
|
2666
2820
|
case "string":
|
|
2667
|
-
if (key.toLowerCase().includes("id")) return "abc123";
|
|
2668
|
-
if (key.toLowerCase().includes("email")) return "user@example.com";
|
|
2669
|
-
if (key.toLowerCase().includes("name")) return "Example";
|
|
2670
|
-
if (key.toLowerCase().includes("url")) return "https://example.com";
|
|
2671
|
-
return "string";
|
|
2821
|
+
if (key.toLowerCase().includes("id")) return fitString(schema, "abc123");
|
|
2822
|
+
if (key.toLowerCase().includes("email")) return fitString(schema, "user@example.com");
|
|
2823
|
+
if (key.toLowerCase().includes("name")) return fitString(schema, "Example");
|
|
2824
|
+
if (key.toLowerCase().includes("url")) return fitString(schema, "https://example.com");
|
|
2825
|
+
return fitString(schema, "string");
|
|
2672
2826
|
case "number":
|
|
2673
2827
|
case "integer":
|
|
2674
2828
|
if (key.toLowerCase().includes("limit")) return 10;
|
|
@@ -2685,24 +2839,88 @@ function getSampleValue(schema, key) {
|
|
|
2685
2839
|
return null;
|
|
2686
2840
|
}
|
|
2687
2841
|
}
|
|
2842
|
+
var PAGINATION_PROPERTIES = ["limit", "offset", "page", "pagesize", "cursor"];
|
|
2843
|
+
function isPaginationProperty(name) {
|
|
2844
|
+
return PAGINATION_PROPERTIES.includes(name.toLowerCase());
|
|
2845
|
+
}
|
|
2688
2846
|
function hasPaginationParams(schema) {
|
|
2689
2847
|
if (!schema || schema.type !== "object" || !schema.properties) {
|
|
2690
2848
|
return false;
|
|
2691
2849
|
}
|
|
2692
|
-
|
|
2693
|
-
return props.some((p) => ["limit", "offset", "page", "pageSize", "cursor"].includes(p.toLowerCase()));
|
|
2850
|
+
return Object.keys(schema.properties).some(isPaginationProperty);
|
|
2694
2851
|
}
|
|
2695
|
-
function
|
|
2696
|
-
|
|
2697
|
-
|
|
2698
|
-
|
|
2699
|
-
const
|
|
2852
|
+
function inputProperties(schema) {
|
|
2853
|
+
if (!schema || schema.type !== "object" || !schema.properties) {
|
|
2854
|
+
return {};
|
|
2855
|
+
}
|
|
2856
|
+
const properties = {};
|
|
2857
|
+
for (const [key, propSchema] of Object.entries(schema.properties)) {
|
|
2858
|
+
if (typeof propSchema !== "boolean") properties[key] = propSchema;
|
|
2859
|
+
}
|
|
2860
|
+
return properties;
|
|
2861
|
+
}
|
|
2862
|
+
function buildExampleArgs(schema, keys, values = {}) {
|
|
2863
|
+
const properties = inputProperties(schema);
|
|
2864
|
+
const args = {};
|
|
2865
|
+
for (const key of [...keys, ...schema?.required ?? []]) {
|
|
2866
|
+
const propSchema = properties[key];
|
|
2867
|
+
if (!propSchema || key in args) continue;
|
|
2868
|
+
args[key] = key in values ? values[key] : getSampleValue(propSchema, key);
|
|
2869
|
+
}
|
|
2870
|
+
return args;
|
|
2871
|
+
}
|
|
2872
|
+
function formatExampleArgs(args) {
|
|
2873
|
+
return Object.keys(args).length > 0 ? JSON.stringify(args, null, 2) : "{}";
|
|
2874
|
+
}
|
|
2875
|
+
function getFilterProperties(schema) {
|
|
2876
|
+
if (!schema || schema.type !== "object" || !schema.properties) {
|
|
2877
|
+
return [];
|
|
2878
|
+
}
|
|
2879
|
+
return Object.keys(schema.properties).filter(
|
|
2880
|
+
(p) => p.toLowerCase().includes("filter") || p.toLowerCase().includes("query") || p.toLowerCase().includes("search") || p.toLowerCase() === "status" || p.toLowerCase() === "type" || p.toLowerCase() === "role"
|
|
2881
|
+
);
|
|
2882
|
+
}
|
|
2883
|
+
function generatePaginationExample(toolName, inputSchema) {
|
|
2884
|
+
const description = `Pagination example for ${toolName}`;
|
|
2885
|
+
const props = Object.keys(inputProperties(inputSchema));
|
|
2886
|
+
const limitKey = props.find((p) => p.toLowerCase() === "limit");
|
|
2887
|
+
const offsetKey = props.find((p) => p.toLowerCase() === "offset");
|
|
2888
|
+
if (limitKey && offsetKey) {
|
|
2889
|
+
const properties = inputProperties(inputSchema);
|
|
2890
|
+
const limit = pickNumber(properties[limitKey], [10]);
|
|
2891
|
+
const firstOffset = pickNumber(properties[offsetKey], [0]);
|
|
2892
|
+
const values = {};
|
|
2893
|
+
if (limit !== void 0) values[limitKey] = limit;
|
|
2894
|
+
if (firstOffset !== void 0) values[offsetKey] = firstOffset;
|
|
2895
|
+
const firstPage = buildExampleArgs(inputSchema, [limitKey, offsetKey], values);
|
|
2896
|
+
const nextOffset = [limit ?? 10, 10, 20, ...properties[offsetKey].enum ?? []].find(
|
|
2897
|
+
(value) => typeof value === "number" && value !== firstPage[offsetKey] && acceptsNumber(properties[offsetKey], value)
|
|
2898
|
+
);
|
|
2899
|
+
if (nextOffset !== void 0) {
|
|
2900
|
+
const secondPage = { ...firstPage, [offsetKey]: nextOffset };
|
|
2901
|
+
return {
|
|
2902
|
+
description,
|
|
2903
|
+
code: `// Fetch first page
|
|
2904
|
+
const page1 = await callTool('${toolName}', ${formatExampleArgs(firstPage)});
|
|
2700
2905
|
|
|
2701
2906
|
// Fetch second page
|
|
2702
|
-
const page2 = await callTool('${toolName}', {
|
|
2907
|
+
const page2 = await callTool('${toolName}', ${formatExampleArgs(secondPage)});
|
|
2703
2908
|
|
|
2704
2909
|
// Combine results
|
|
2705
2910
|
return [...page1.items, ...page2.items];`
|
|
2911
|
+
};
|
|
2912
|
+
}
|
|
2913
|
+
return {
|
|
2914
|
+
description,
|
|
2915
|
+
code: `const page = await callTool('${toolName}', ${formatExampleArgs(firstPage)});
|
|
2916
|
+
return page.items || page;`
|
|
2917
|
+
};
|
|
2918
|
+
}
|
|
2919
|
+
const args = buildExampleArgs(inputSchema, props.filter(isPaginationProperty));
|
|
2920
|
+
return {
|
|
2921
|
+
description,
|
|
2922
|
+
code: `const page = await callTool('${toolName}', ${formatExampleArgs(args)});
|
|
2923
|
+
return page.items || page;`
|
|
2706
2924
|
};
|
|
2707
2925
|
}
|
|
2708
2926
|
function extractEntityName(toolName) {
|
|
@@ -2720,13 +2938,18 @@ function generateCreateExample(toolName, inputSchema) {
|
|
|
2720
2938
|
return result;`
|
|
2721
2939
|
};
|
|
2722
2940
|
}
|
|
2941
|
+
function idArgs(schema, idParam) {
|
|
2942
|
+
const idSchema = inputProperties(schema)[idParam];
|
|
2943
|
+
const values = isFreeTextString(idSchema) ? { [idParam]: fitString(idSchema, "abc123") } : {};
|
|
2944
|
+
return buildExampleArgs(schema, [idParam], values);
|
|
2945
|
+
}
|
|
2723
2946
|
function generateGetExample(toolName, inputSchema) {
|
|
2724
2947
|
const entity = extractEntityName(toolName);
|
|
2725
2948
|
const idParam = findIdParameter(inputSchema);
|
|
2726
2949
|
if (idParam) {
|
|
2727
2950
|
return {
|
|
2728
2951
|
description: `Get ${entity} by ${idParam}`,
|
|
2729
|
-
code: `const ${entity} = await callTool('${toolName}', {
|
|
2952
|
+
code: `const ${entity} = await callTool('${toolName}', ${formatInlineArgs(idArgs(inputSchema, idParam))});
|
|
2730
2953
|
return ${entity};`
|
|
2731
2954
|
};
|
|
2732
2955
|
}
|
|
@@ -2742,7 +2965,7 @@ function generateListExample(toolName, inputSchema) {
|
|
|
2742
2965
|
const entity = extractEntityName(toolName);
|
|
2743
2966
|
return {
|
|
2744
2967
|
description: `List all ${entity}s`,
|
|
2745
|
-
code: `const result = await callTool('${toolName}', {});
|
|
2968
|
+
code: `const result = await callTool('${toolName}', ${formatExampleArgs(buildExampleArgs(inputSchema, []))});
|
|
2746
2969
|
return result.items || result;`
|
|
2747
2970
|
};
|
|
2748
2971
|
}
|
|
@@ -2752,10 +2975,11 @@ function generateUpdateExample(toolName, inputSchema) {
|
|
|
2752
2975
|
const updateFields = generateUpdateFields(inputSchema);
|
|
2753
2976
|
const fieldsStr = updateFields ? JSON.stringify(updateFields, null, 2).replace(/\n/g, "\n ") : "{ /* fields to update */ }";
|
|
2754
2977
|
if (idParam) {
|
|
2978
|
+
const identifiers = formatInlineArgs(idArgs(inputSchema, idParam)).slice(2, -2);
|
|
2755
2979
|
return {
|
|
2756
2980
|
description: `Update ${entity} by ${idParam}`,
|
|
2757
2981
|
code: `const updated = await callTool('${toolName}', {
|
|
2758
|
-
${
|
|
2982
|
+
${identifiers},
|
|
2759
2983
|
...${fieldsStr}
|
|
2760
2984
|
});
|
|
2761
2985
|
return updated;`
|
|
@@ -2773,7 +2997,7 @@ function generateDeleteExample(toolName, inputSchema) {
|
|
|
2773
2997
|
if (idParam) {
|
|
2774
2998
|
return {
|
|
2775
2999
|
description: `Delete ${entity} by ${idParam}`,
|
|
2776
|
-
code: `const result = await callTool('${toolName}', {
|
|
3000
|
+
code: `const result = await callTool('${toolName}', ${formatInlineArgs(idArgs(inputSchema, idParam))});
|
|
2777
3001
|
return result;`
|
|
2778
3002
|
};
|
|
2779
3003
|
}
|
|
@@ -2787,17 +3011,18 @@ return result;`
|
|
|
2787
3011
|
}
|
|
2788
3012
|
function generateSearchExample(toolName, inputSchema) {
|
|
2789
3013
|
const entity = extractEntityName(toolName);
|
|
2790
|
-
const
|
|
2791
|
-
|
|
2792
|
-
|
|
2793
|
-
|
|
2794
|
-
|
|
2795
|
-
|
|
2796
|
-
|
|
2797
|
-
|
|
3014
|
+
const searchParam = findQueryParameter(inputSchema) ?? getFilterProperties(inputSchema)[0];
|
|
3015
|
+
const searchSchema = searchParam ? inputProperties(inputSchema)[searchParam] : void 0;
|
|
3016
|
+
const required = new Set(inputSchema?.required ?? []);
|
|
3017
|
+
const unfillable = searchSchema?.type === "string" && (searchSchema.pattern !== void 0 || searchSchema.format !== void 0) && searchSchema.enum === void 0 && searchSchema.const === void 0 && searchSchema.default === void 0 && !required.has(searchParam ?? "");
|
|
3018
|
+
const args = searchParam && !unfillable ? buildExampleArgs(
|
|
3019
|
+
inputSchema,
|
|
3020
|
+
[searchParam],
|
|
3021
|
+
isFreeTextString(searchSchema) && searchSchema ? { [searchParam]: fitString(searchSchema, "search term") } : {}
|
|
3022
|
+
) : buildExampleArgs(inputSchema, []);
|
|
2798
3023
|
return {
|
|
2799
3024
|
description: `Search for ${entity}s`,
|
|
2800
|
-
code: `const results = await callTool('${toolName}', {
|
|
3025
|
+
code: `const results = await callTool('${toolName}', ${formatExampleArgs(args)});
|
|
2801
3026
|
return results.items || results;`
|
|
2802
3027
|
};
|
|
2803
3028
|
}
|
|
@@ -2854,7 +3079,7 @@ function generateSmartExample(toolName, inputSchema, description) {
|
|
|
2854
3079
|
case "get":
|
|
2855
3080
|
return generateGetExample(toolName, inputSchema);
|
|
2856
3081
|
case "list":
|
|
2857
|
-
return hasPaginationParams(inputSchema) ? generatePaginationExample(toolName) : generateListExample(toolName, inputSchema);
|
|
3082
|
+
return hasPaginationParams(inputSchema) ? generatePaginationExample(toolName, inputSchema) : generateListExample(toolName, inputSchema);
|
|
2858
3083
|
case "update":
|
|
2859
3084
|
return generateUpdateExample(toolName, inputSchema);
|
|
2860
3085
|
case "delete":
|
|
@@ -3082,7 +3307,9 @@ var DescribeTool = class extends ToolContext4 {
|
|
|
3082
3307
|
*
|
|
3083
3308
|
* Priority:
|
|
3084
3309
|
* 1. User-provided examples from @Tool decorator metadata (up to 5)
|
|
3085
|
-
* 2.
|
|
3310
|
+
* 2. Without any, one smart intent-based example built from the input schema. It is never added
|
|
3311
|
+
* next to the tool's own examples: those show how the tool is called, and a generated one
|
|
3312
|
+
* only guesses (#647).
|
|
3086
3313
|
* 3. Returns at least 1 example
|
|
3087
3314
|
*/
|
|
3088
3315
|
generateExamples(tool, inputSchema) {
|
|
@@ -3097,7 +3324,7 @@ return result;`
|
|
|
3097
3324
|
});
|
|
3098
3325
|
}
|
|
3099
3326
|
}
|
|
3100
|
-
if (result.length
|
|
3327
|
+
if (result.length === 0) {
|
|
3101
3328
|
result.push(generateSmartExample(tool.name, inputSchema, tool.metadata?.description));
|
|
3102
3329
|
}
|
|
3103
3330
|
return result.slice(0, 5);
|
|
@@ -3186,7 +3413,11 @@ var runtimeErrorPayloadSchema = z7.object({
|
|
|
3186
3413
|
var toolErrorPayloadSchema = z7.object({
|
|
3187
3414
|
source: z7.literal("tool"),
|
|
3188
3415
|
toolName: z7.string(),
|
|
3189
|
-
|
|
3416
|
+
/**
|
|
3417
|
+
* @deprecated Never set: the sandbox resolves sidecar references in a call's arguments before
|
|
3418
|
+
* the tool sees them, so they may hold data the script itself never had.
|
|
3419
|
+
*/
|
|
3420
|
+
toolInput: z7.unknown().optional(),
|
|
3190
3421
|
message: z7.string(),
|
|
3191
3422
|
code: z7.string().optional(),
|
|
3192
3423
|
/** @deprecated Never set: the enclave's error data is not sanitized for clients. */
|
|
@@ -3433,10 +3664,10 @@ var ExecuteTool = class extends ToolContext5 {
|
|
|
3433
3664
|
error: {
|
|
3434
3665
|
source: "tool",
|
|
3435
3666
|
toolName: error.toolName,
|
|
3436
|
-
toolInput: error.toolInput,
|
|
3437
3667
|
message: toClientErrorMessage(error.message),
|
|
3438
3668
|
code: error.code
|
|
3439
|
-
// No `details`: the enclave's error data is not sanitized for clients.
|
|
3669
|
+
// No `details`: the enclave's error data is not sanitized for clients. No `toolInput`:
|
|
3670
|
+
// the arguments the tool saw may hold sidecar-resolved data the script never had.
|
|
3440
3671
|
}
|
|
3441
3672
|
};
|
|
3442
3673
|
}
|
package/esm/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@frontmcp/plugin-codecall",
|
|
3
|
-
"version": "1.8.
|
|
3
|
+
"version": "1.8.6",
|
|
4
4
|
"description": "CodeCall plugin for FrontMCP - AgentScript-based meta-tools for orchestrating MCP tools",
|
|
5
5
|
"author": "AgentFront <info@agentfront.dev>",
|
|
6
6
|
"license": "Apache-2.0",
|
|
@@ -48,14 +48,16 @@
|
|
|
48
48
|
}
|
|
49
49
|
},
|
|
50
50
|
"dependencies": {
|
|
51
|
+
"@enclave-vm/ast": "^2.15.3",
|
|
51
52
|
"@enclave-vm/core": "^2.15.3",
|
|
52
|
-
"@frontmcp/protocol": "1.8.
|
|
53
|
-
"@frontmcp/sdk": "1.8.
|
|
53
|
+
"@frontmcp/protocol": "1.8.6",
|
|
54
|
+
"@frontmcp/sdk": "1.8.6",
|
|
55
|
+
"acorn": "^8.15.0",
|
|
54
56
|
"vectoriadb": "^2.3.2"
|
|
55
57
|
},
|
|
56
58
|
"peerDependencies": {
|
|
57
|
-
"@frontmcp/lazy-zod": "1.8.
|
|
58
|
-
"@frontmcp/plugin-cache": "1.8.
|
|
59
|
+
"@frontmcp/lazy-zod": "1.8.6",
|
|
60
|
+
"@frontmcp/plugin-cache": "1.8.6"
|
|
59
61
|
},
|
|
60
62
|
"devDependencies": {
|
|
61
63
|
"reflect-metadata": "^0.2.2"
|
package/index.js
CHANGED
|
@@ -1908,6 +1908,121 @@ function toSandboxToolNamespaces(namespaces, reservedGlobals = []) {
|
|
|
1908
1908
|
return count > 0 ? bindable : void 0;
|
|
1909
1909
|
}
|
|
1910
1910
|
|
|
1911
|
+
// plugins/plugin-codecall/src/utils/script-lines.ts
|
|
1912
|
+
var import_ast = require("@enclave-vm/ast");
|
|
1913
|
+
var acorn = __toESM(require("acorn"));
|
|
1914
|
+
var PARSE_OPTIONS = { ecmaVersion: "latest", locations: true };
|
|
1915
|
+
var NON_CHILD_KEYS = /* @__PURE__ */ new Set(["type", "loc", "start", "end", "range"]);
|
|
1916
|
+
function isNode(value) {
|
|
1917
|
+
return typeof value === "object" && value !== null && typeof value.type === "string";
|
|
1918
|
+
}
|
|
1919
|
+
function isAddedByTransform(node) {
|
|
1920
|
+
if (node.type === "VariableDeclaration") {
|
|
1921
|
+
const [declaration] = node["declarations"] ?? [];
|
|
1922
|
+
const id = declaration?.["id"];
|
|
1923
|
+
return typeof id?.["name"] === "string" && id["name"].startsWith("__iter_");
|
|
1924
|
+
}
|
|
1925
|
+
if (node.type === "IfStatement") {
|
|
1926
|
+
const right = node["test"]?.["right"];
|
|
1927
|
+
return right?.type === "Identifier" && right["name"] === "__maxIterations";
|
|
1928
|
+
}
|
|
1929
|
+
return false;
|
|
1930
|
+
}
|
|
1931
|
+
function parseScript(script) {
|
|
1932
|
+
try {
|
|
1933
|
+
return { body: parseBody(script, "script"), offset: 0 };
|
|
1934
|
+
} catch {
|
|
1935
|
+
try {
|
|
1936
|
+
return { body: parseBody(script, "module"), offset: 0 };
|
|
1937
|
+
} catch {
|
|
1938
|
+
const wrapped = parseBody(`async function __temp__() {
|
|
1939
|
+
${script}
|
|
1940
|
+
}`, "script");
|
|
1941
|
+
const fn = wrapped[0];
|
|
1942
|
+
const block = fn?.["body"];
|
|
1943
|
+
return { body: block?.["body"] ?? [], offset: 1 };
|
|
1944
|
+
}
|
|
1945
|
+
}
|
|
1946
|
+
}
|
|
1947
|
+
function parseBody(code, sourceType) {
|
|
1948
|
+
const program = acorn.parse(code, { ...PARSE_OPTIONS, sourceType });
|
|
1949
|
+
return program["body"] ?? [];
|
|
1950
|
+
}
|
|
1951
|
+
function treesOf(script) {
|
|
1952
|
+
try {
|
|
1953
|
+
const wrap = !(0, import_ast.isWrappedInMain)(script);
|
|
1954
|
+
const printed = parseBody((0, import_ast.transformAgentScript)(script, { wrapInMain: wrap }), "script");
|
|
1955
|
+
const { body, offset } = parseScript(script);
|
|
1956
|
+
if (!wrap) return { printed, script: body, offset };
|
|
1957
|
+
const main = printed[0]?.["body"];
|
|
1958
|
+
return { printed: main?.["body"] ?? [], script: body, offset };
|
|
1959
|
+
} catch {
|
|
1960
|
+
return void 0;
|
|
1961
|
+
}
|
|
1962
|
+
}
|
|
1963
|
+
function pairLists(printed, script, depth, out, offset) {
|
|
1964
|
+
const kept = printed.filter((node) => !(isNode(node) && isAddedByTransform(node)));
|
|
1965
|
+
if (kept.length !== script.length) return;
|
|
1966
|
+
kept.forEach((node, index) => {
|
|
1967
|
+
const own = script[index];
|
|
1968
|
+
if (isNode(node) && isNode(own)) pairNodes(node, own, depth, out, offset);
|
|
1969
|
+
});
|
|
1970
|
+
}
|
|
1971
|
+
function pairNodes(printed, script, depth, out, offset) {
|
|
1972
|
+
if (printed.type === "ReturnStatement" && script.type === "ExpressionStatement") {
|
|
1973
|
+
record(printed, script, depth, out, offset);
|
|
1974
|
+
const argument = printed["argument"];
|
|
1975
|
+
const expression = script["expression"];
|
|
1976
|
+
if (isNode(argument) && isNode(expression)) pairNodes(argument, expression, depth + 1, out, offset);
|
|
1977
|
+
return;
|
|
1978
|
+
}
|
|
1979
|
+
if (printed.type !== script.type) return;
|
|
1980
|
+
record(printed, script, depth, out, offset);
|
|
1981
|
+
for (const key of Object.keys(printed)) {
|
|
1982
|
+
if (NON_CHILD_KEYS.has(key)) continue;
|
|
1983
|
+
const printedChild = printed[key];
|
|
1984
|
+
const scriptChild = script[key];
|
|
1985
|
+
if (Array.isArray(printedChild) && Array.isArray(scriptChild)) {
|
|
1986
|
+
pairLists(printedChild, scriptChild, depth + 1, out, offset);
|
|
1987
|
+
} else if (isNode(printedChild) && isNode(scriptChild)) {
|
|
1988
|
+
pairNodes(printedChild, scriptChild, depth + 1, out, offset);
|
|
1989
|
+
}
|
|
1990
|
+
}
|
|
1991
|
+
}
|
|
1992
|
+
function record(printed, script, depth, out, offset) {
|
|
1993
|
+
if (!printed.loc || !script.loc) return;
|
|
1994
|
+
out.push({
|
|
1995
|
+
printedStart: printed.loc.start.line,
|
|
1996
|
+
printedEnd: printed.loc.end.line,
|
|
1997
|
+
scriptLine: script.loc.start.line - offset,
|
|
1998
|
+
depth
|
|
1999
|
+
});
|
|
2000
|
+
}
|
|
2001
|
+
function validatedLineMapper(script) {
|
|
2002
|
+
const trees = treesOf(script);
|
|
2003
|
+
if (!trees) return () => void 0;
|
|
2004
|
+
const pairs = [];
|
|
2005
|
+
pairLists(trees.printed, trees.script, 0, pairs, trees.offset);
|
|
2006
|
+
return (printedLine) => {
|
|
2007
|
+
const starting = pairs.filter((pair) => pair.printedStart === printedLine);
|
|
2008
|
+
const candidates = starting.length > 0 ? starting : pairs.filter((pair) => pair.printedStart <= printedLine && printedLine <= pair.printedEnd);
|
|
2009
|
+
const best = candidates.reduce(
|
|
2010
|
+
(deepest, pair) => !deepest || pair.depth > deepest.depth ? pair : deepest,
|
|
2011
|
+
void 0
|
|
2012
|
+
);
|
|
2013
|
+
return best && best.scriptLine >= 1 ? best.scriptLine : void 0;
|
|
2014
|
+
};
|
|
2015
|
+
}
|
|
2016
|
+
var ISSUE_LINE_RE = / \(line (\d+)\)/g;
|
|
2017
|
+
function withScriptLines(message, script) {
|
|
2018
|
+
if (!message.includes("(line ")) return message;
|
|
2019
|
+
const lineOf = validatedLineMapper(script);
|
|
2020
|
+
return message.replace(ISSUE_LINE_RE, (_match, printed) => {
|
|
2021
|
+
const line = lineOf(Number(printed));
|
|
2022
|
+
return line === void 0 ? "" : ` (line ${line})`;
|
|
2023
|
+
});
|
|
2024
|
+
}
|
|
2025
|
+
|
|
1911
2026
|
// plugins/plugin-codecall/src/services/enclave.service.ts
|
|
1912
2027
|
function toolFailureMessage(error, toolName) {
|
|
1913
2028
|
if (typeof error === "string" && error) return error;
|
|
@@ -2032,7 +2147,7 @@ var EnclaveService = class {
|
|
|
2032
2147
|
const enclave = createEnclave(options);
|
|
2033
2148
|
try {
|
|
2034
2149
|
const result = await enclave.run(code);
|
|
2035
|
-
return this.mapEnclaveResult(result, logs, toolFailures);
|
|
2150
|
+
return this.mapEnclaveResult(result, logs, toolFailures, code);
|
|
2036
2151
|
} finally {
|
|
2037
2152
|
enclave.dispose();
|
|
2038
2153
|
}
|
|
@@ -2040,7 +2155,7 @@ var EnclaveService = class {
|
|
|
2040
2155
|
/**
|
|
2041
2156
|
* Map Enclave ExecutionResult to EnclaveExecutionResult
|
|
2042
2157
|
*/
|
|
2043
|
-
mapEnclaveResult(result, logs, toolFailures = []) {
|
|
2158
|
+
mapEnclaveResult(result, logs, toolFailures = [], script = "") {
|
|
2044
2159
|
const stats = {
|
|
2045
2160
|
duration: result.stats.duration,
|
|
2046
2161
|
toolCallCount: result.stats.toolCallCount,
|
|
@@ -2082,7 +2197,9 @@ var EnclaveService = class {
|
|
|
2082
2197
|
return {
|
|
2083
2198
|
success: false,
|
|
2084
2199
|
error: {
|
|
2085
|
-
|
|
2200
|
+
// The enclave names lines of the code it validated (the script wrapped and printed again),
|
|
2201
|
+
// not the script's own.
|
|
2202
|
+
message: withScriptLines(error.message, script),
|
|
2086
2203
|
name: "ValidationError",
|
|
2087
2204
|
code: error.code,
|
|
2088
2205
|
...blockedPatterns.length > 0 ? { blockedPatterns } : {}
|
|
@@ -2688,6 +2805,43 @@ function generateSampleParams(schema) {
|
|
|
2688
2805
|
}
|
|
2689
2806
|
return Object.keys(params).length > 0 ? params : null;
|
|
2690
2807
|
}
|
|
2808
|
+
function fitString(schema, value) {
|
|
2809
|
+
let fitted = value;
|
|
2810
|
+
if (schema.maxLength !== void 0 && fitted.length > schema.maxLength) {
|
|
2811
|
+
fitted = fitted.slice(0, Math.max(0, schema.maxLength));
|
|
2812
|
+
}
|
|
2813
|
+
if (schema.minLength !== void 0 && fitted.length < schema.minLength) {
|
|
2814
|
+
fitted = fitted.padEnd(schema.minLength, "x");
|
|
2815
|
+
}
|
|
2816
|
+
return fitted;
|
|
2817
|
+
}
|
|
2818
|
+
function isFreeTextString(schema) {
|
|
2819
|
+
return schema?.type === "string" && schema.enum === void 0 && schema.const === void 0 && schema.default === void 0 && schema.pattern === void 0 && schema.format === void 0;
|
|
2820
|
+
}
|
|
2821
|
+
function acceptsNumber(schema, value) {
|
|
2822
|
+
if (schema.const !== void 0) return schema.const === value;
|
|
2823
|
+
if (schema.enum !== void 0) return schema.enum.includes(value);
|
|
2824
|
+
if (schema.minimum !== void 0 && value < schema.minimum) return false;
|
|
2825
|
+
if (schema.maximum !== void 0 && value > schema.maximum) return false;
|
|
2826
|
+
return true;
|
|
2827
|
+
}
|
|
2828
|
+
function pickNumber(schema, preferred) {
|
|
2829
|
+
const accepted = preferred.find((value) => acceptsNumber(schema, value));
|
|
2830
|
+
if (accepted !== void 0) return accepted;
|
|
2831
|
+
const named = [schema.const, schema.enum?.[0], schema.minimum, schema.maximum].find(
|
|
2832
|
+
(value) => typeof value === "number" && acceptsNumber(schema, value)
|
|
2833
|
+
);
|
|
2834
|
+
return named;
|
|
2835
|
+
}
|
|
2836
|
+
function formatInlineArgs(args) {
|
|
2837
|
+
const entries = Object.entries(args).map(([key, value]) => {
|
|
2838
|
+
const name = /^[A-Za-z_$][\w$]*$/.test(key) ? key : JSON.stringify(key);
|
|
2839
|
+
const plain = typeof value === "string" && [...value].every((ch) => ch !== "'" && ch !== "\\" && ch >= " ");
|
|
2840
|
+
const literal = plain ? `'${value}'` : JSON.stringify(value);
|
|
2841
|
+
return `${name}: ${literal}`;
|
|
2842
|
+
});
|
|
2843
|
+
return entries.length > 0 ? `{ ${entries.join(", ")} }` : "{}";
|
|
2844
|
+
}
|
|
2691
2845
|
function getSampleValue(schema, key) {
|
|
2692
2846
|
if (schema.default !== void 0) {
|
|
2693
2847
|
return schema.default;
|
|
@@ -2701,11 +2855,11 @@ function getSampleValue(schema, key) {
|
|
|
2701
2855
|
const type = Array.isArray(schema.type) ? schema.type[0] : schema.type;
|
|
2702
2856
|
switch (type) {
|
|
2703
2857
|
case "string":
|
|
2704
|
-
if (key.toLowerCase().includes("id")) return "abc123";
|
|
2705
|
-
if (key.toLowerCase().includes("email")) return "user@example.com";
|
|
2706
|
-
if (key.toLowerCase().includes("name")) return "Example";
|
|
2707
|
-
if (key.toLowerCase().includes("url")) return "https://example.com";
|
|
2708
|
-
return "string";
|
|
2858
|
+
if (key.toLowerCase().includes("id")) return fitString(schema, "abc123");
|
|
2859
|
+
if (key.toLowerCase().includes("email")) return fitString(schema, "user@example.com");
|
|
2860
|
+
if (key.toLowerCase().includes("name")) return fitString(schema, "Example");
|
|
2861
|
+
if (key.toLowerCase().includes("url")) return fitString(schema, "https://example.com");
|
|
2862
|
+
return fitString(schema, "string");
|
|
2709
2863
|
case "number":
|
|
2710
2864
|
case "integer":
|
|
2711
2865
|
if (key.toLowerCase().includes("limit")) return 10;
|
|
@@ -2722,24 +2876,88 @@ function getSampleValue(schema, key) {
|
|
|
2722
2876
|
return null;
|
|
2723
2877
|
}
|
|
2724
2878
|
}
|
|
2879
|
+
var PAGINATION_PROPERTIES = ["limit", "offset", "page", "pagesize", "cursor"];
|
|
2880
|
+
function isPaginationProperty(name) {
|
|
2881
|
+
return PAGINATION_PROPERTIES.includes(name.toLowerCase());
|
|
2882
|
+
}
|
|
2725
2883
|
function hasPaginationParams(schema) {
|
|
2726
2884
|
if (!schema || schema.type !== "object" || !schema.properties) {
|
|
2727
2885
|
return false;
|
|
2728
2886
|
}
|
|
2729
|
-
|
|
2730
|
-
return props.some((p) => ["limit", "offset", "page", "pageSize", "cursor"].includes(p.toLowerCase()));
|
|
2887
|
+
return Object.keys(schema.properties).some(isPaginationProperty);
|
|
2731
2888
|
}
|
|
2732
|
-
function
|
|
2733
|
-
|
|
2734
|
-
|
|
2735
|
-
|
|
2736
|
-
const
|
|
2889
|
+
function inputProperties(schema) {
|
|
2890
|
+
if (!schema || schema.type !== "object" || !schema.properties) {
|
|
2891
|
+
return {};
|
|
2892
|
+
}
|
|
2893
|
+
const properties = {};
|
|
2894
|
+
for (const [key, propSchema] of Object.entries(schema.properties)) {
|
|
2895
|
+
if (typeof propSchema !== "boolean") properties[key] = propSchema;
|
|
2896
|
+
}
|
|
2897
|
+
return properties;
|
|
2898
|
+
}
|
|
2899
|
+
function buildExampleArgs(schema, keys, values = {}) {
|
|
2900
|
+
const properties = inputProperties(schema);
|
|
2901
|
+
const args = {};
|
|
2902
|
+
for (const key of [...keys, ...schema?.required ?? []]) {
|
|
2903
|
+
const propSchema = properties[key];
|
|
2904
|
+
if (!propSchema || key in args) continue;
|
|
2905
|
+
args[key] = key in values ? values[key] : getSampleValue(propSchema, key);
|
|
2906
|
+
}
|
|
2907
|
+
return args;
|
|
2908
|
+
}
|
|
2909
|
+
function formatExampleArgs(args) {
|
|
2910
|
+
return Object.keys(args).length > 0 ? JSON.stringify(args, null, 2) : "{}";
|
|
2911
|
+
}
|
|
2912
|
+
function getFilterProperties(schema) {
|
|
2913
|
+
if (!schema || schema.type !== "object" || !schema.properties) {
|
|
2914
|
+
return [];
|
|
2915
|
+
}
|
|
2916
|
+
return Object.keys(schema.properties).filter(
|
|
2917
|
+
(p) => p.toLowerCase().includes("filter") || p.toLowerCase().includes("query") || p.toLowerCase().includes("search") || p.toLowerCase() === "status" || p.toLowerCase() === "type" || p.toLowerCase() === "role"
|
|
2918
|
+
);
|
|
2919
|
+
}
|
|
2920
|
+
function generatePaginationExample(toolName, inputSchema) {
|
|
2921
|
+
const description = `Pagination example for ${toolName}`;
|
|
2922
|
+
const props = Object.keys(inputProperties(inputSchema));
|
|
2923
|
+
const limitKey = props.find((p) => p.toLowerCase() === "limit");
|
|
2924
|
+
const offsetKey = props.find((p) => p.toLowerCase() === "offset");
|
|
2925
|
+
if (limitKey && offsetKey) {
|
|
2926
|
+
const properties = inputProperties(inputSchema);
|
|
2927
|
+
const limit = pickNumber(properties[limitKey], [10]);
|
|
2928
|
+
const firstOffset = pickNumber(properties[offsetKey], [0]);
|
|
2929
|
+
const values = {};
|
|
2930
|
+
if (limit !== void 0) values[limitKey] = limit;
|
|
2931
|
+
if (firstOffset !== void 0) values[offsetKey] = firstOffset;
|
|
2932
|
+
const firstPage = buildExampleArgs(inputSchema, [limitKey, offsetKey], values);
|
|
2933
|
+
const nextOffset = [limit ?? 10, 10, 20, ...properties[offsetKey].enum ?? []].find(
|
|
2934
|
+
(value) => typeof value === "number" && value !== firstPage[offsetKey] && acceptsNumber(properties[offsetKey], value)
|
|
2935
|
+
);
|
|
2936
|
+
if (nextOffset !== void 0) {
|
|
2937
|
+
const secondPage = { ...firstPage, [offsetKey]: nextOffset };
|
|
2938
|
+
return {
|
|
2939
|
+
description,
|
|
2940
|
+
code: `// Fetch first page
|
|
2941
|
+
const page1 = await callTool('${toolName}', ${formatExampleArgs(firstPage)});
|
|
2737
2942
|
|
|
2738
2943
|
// Fetch second page
|
|
2739
|
-
const page2 = await callTool('${toolName}', {
|
|
2944
|
+
const page2 = await callTool('${toolName}', ${formatExampleArgs(secondPage)});
|
|
2740
2945
|
|
|
2741
2946
|
// Combine results
|
|
2742
2947
|
return [...page1.items, ...page2.items];`
|
|
2948
|
+
};
|
|
2949
|
+
}
|
|
2950
|
+
return {
|
|
2951
|
+
description,
|
|
2952
|
+
code: `const page = await callTool('${toolName}', ${formatExampleArgs(firstPage)});
|
|
2953
|
+
return page.items || page;`
|
|
2954
|
+
};
|
|
2955
|
+
}
|
|
2956
|
+
const args = buildExampleArgs(inputSchema, props.filter(isPaginationProperty));
|
|
2957
|
+
return {
|
|
2958
|
+
description,
|
|
2959
|
+
code: `const page = await callTool('${toolName}', ${formatExampleArgs(args)});
|
|
2960
|
+
return page.items || page;`
|
|
2743
2961
|
};
|
|
2744
2962
|
}
|
|
2745
2963
|
function extractEntityName(toolName) {
|
|
@@ -2757,13 +2975,18 @@ function generateCreateExample(toolName, inputSchema) {
|
|
|
2757
2975
|
return result;`
|
|
2758
2976
|
};
|
|
2759
2977
|
}
|
|
2978
|
+
function idArgs(schema, idParam) {
|
|
2979
|
+
const idSchema = inputProperties(schema)[idParam];
|
|
2980
|
+
const values = isFreeTextString(idSchema) ? { [idParam]: fitString(idSchema, "abc123") } : {};
|
|
2981
|
+
return buildExampleArgs(schema, [idParam], values);
|
|
2982
|
+
}
|
|
2760
2983
|
function generateGetExample(toolName, inputSchema) {
|
|
2761
2984
|
const entity = extractEntityName(toolName);
|
|
2762
2985
|
const idParam = findIdParameter(inputSchema);
|
|
2763
2986
|
if (idParam) {
|
|
2764
2987
|
return {
|
|
2765
2988
|
description: `Get ${entity} by ${idParam}`,
|
|
2766
|
-
code: `const ${entity} = await callTool('${toolName}', {
|
|
2989
|
+
code: `const ${entity} = await callTool('${toolName}', ${formatInlineArgs(idArgs(inputSchema, idParam))});
|
|
2767
2990
|
return ${entity};`
|
|
2768
2991
|
};
|
|
2769
2992
|
}
|
|
@@ -2779,7 +3002,7 @@ function generateListExample(toolName, inputSchema) {
|
|
|
2779
3002
|
const entity = extractEntityName(toolName);
|
|
2780
3003
|
return {
|
|
2781
3004
|
description: `List all ${entity}s`,
|
|
2782
|
-
code: `const result = await callTool('${toolName}', {});
|
|
3005
|
+
code: `const result = await callTool('${toolName}', ${formatExampleArgs(buildExampleArgs(inputSchema, []))});
|
|
2783
3006
|
return result.items || result;`
|
|
2784
3007
|
};
|
|
2785
3008
|
}
|
|
@@ -2789,10 +3012,11 @@ function generateUpdateExample(toolName, inputSchema) {
|
|
|
2789
3012
|
const updateFields = generateUpdateFields(inputSchema);
|
|
2790
3013
|
const fieldsStr = updateFields ? JSON.stringify(updateFields, null, 2).replace(/\n/g, "\n ") : "{ /* fields to update */ }";
|
|
2791
3014
|
if (idParam) {
|
|
3015
|
+
const identifiers = formatInlineArgs(idArgs(inputSchema, idParam)).slice(2, -2);
|
|
2792
3016
|
return {
|
|
2793
3017
|
description: `Update ${entity} by ${idParam}`,
|
|
2794
3018
|
code: `const updated = await callTool('${toolName}', {
|
|
2795
|
-
${
|
|
3019
|
+
${identifiers},
|
|
2796
3020
|
...${fieldsStr}
|
|
2797
3021
|
});
|
|
2798
3022
|
return updated;`
|
|
@@ -2810,7 +3034,7 @@ function generateDeleteExample(toolName, inputSchema) {
|
|
|
2810
3034
|
if (idParam) {
|
|
2811
3035
|
return {
|
|
2812
3036
|
description: `Delete ${entity} by ${idParam}`,
|
|
2813
|
-
code: `const result = await callTool('${toolName}', {
|
|
3037
|
+
code: `const result = await callTool('${toolName}', ${formatInlineArgs(idArgs(inputSchema, idParam))});
|
|
2814
3038
|
return result;`
|
|
2815
3039
|
};
|
|
2816
3040
|
}
|
|
@@ -2824,17 +3048,18 @@ return result;`
|
|
|
2824
3048
|
}
|
|
2825
3049
|
function generateSearchExample(toolName, inputSchema) {
|
|
2826
3050
|
const entity = extractEntityName(toolName);
|
|
2827
|
-
const
|
|
2828
|
-
|
|
2829
|
-
|
|
2830
|
-
|
|
2831
|
-
|
|
2832
|
-
|
|
2833
|
-
|
|
2834
|
-
|
|
3051
|
+
const searchParam = findQueryParameter(inputSchema) ?? getFilterProperties(inputSchema)[0];
|
|
3052
|
+
const searchSchema = searchParam ? inputProperties(inputSchema)[searchParam] : void 0;
|
|
3053
|
+
const required = new Set(inputSchema?.required ?? []);
|
|
3054
|
+
const unfillable = searchSchema?.type === "string" && (searchSchema.pattern !== void 0 || searchSchema.format !== void 0) && searchSchema.enum === void 0 && searchSchema.const === void 0 && searchSchema.default === void 0 && !required.has(searchParam ?? "");
|
|
3055
|
+
const args = searchParam && !unfillable ? buildExampleArgs(
|
|
3056
|
+
inputSchema,
|
|
3057
|
+
[searchParam],
|
|
3058
|
+
isFreeTextString(searchSchema) && searchSchema ? { [searchParam]: fitString(searchSchema, "search term") } : {}
|
|
3059
|
+
) : buildExampleArgs(inputSchema, []);
|
|
2835
3060
|
return {
|
|
2836
3061
|
description: `Search for ${entity}s`,
|
|
2837
|
-
code: `const results = await callTool('${toolName}', {
|
|
3062
|
+
code: `const results = await callTool('${toolName}', ${formatExampleArgs(args)});
|
|
2838
3063
|
return results.items || results;`
|
|
2839
3064
|
};
|
|
2840
3065
|
}
|
|
@@ -2891,7 +3116,7 @@ function generateSmartExample(toolName, inputSchema, description) {
|
|
|
2891
3116
|
case "get":
|
|
2892
3117
|
return generateGetExample(toolName, inputSchema);
|
|
2893
3118
|
case "list":
|
|
2894
|
-
return hasPaginationParams(inputSchema) ? generatePaginationExample(toolName) : generateListExample(toolName, inputSchema);
|
|
3119
|
+
return hasPaginationParams(inputSchema) ? generatePaginationExample(toolName, inputSchema) : generateListExample(toolName, inputSchema);
|
|
2895
3120
|
case "update":
|
|
2896
3121
|
return generateUpdateExample(toolName, inputSchema);
|
|
2897
3122
|
case "delete":
|
|
@@ -3119,7 +3344,9 @@ var DescribeTool = class extends import_sdk7.ToolContext {
|
|
|
3119
3344
|
*
|
|
3120
3345
|
* Priority:
|
|
3121
3346
|
* 1. User-provided examples from @Tool decorator metadata (up to 5)
|
|
3122
|
-
* 2.
|
|
3347
|
+
* 2. Without any, one smart intent-based example built from the input schema. It is never added
|
|
3348
|
+
* next to the tool's own examples: those show how the tool is called, and a generated one
|
|
3349
|
+
* only guesses (#647).
|
|
3123
3350
|
* 3. Returns at least 1 example
|
|
3124
3351
|
*/
|
|
3125
3352
|
generateExamples(tool, inputSchema) {
|
|
@@ -3134,7 +3361,7 @@ return result;`
|
|
|
3134
3361
|
});
|
|
3135
3362
|
}
|
|
3136
3363
|
}
|
|
3137
|
-
if (result.length
|
|
3364
|
+
if (result.length === 0) {
|
|
3138
3365
|
result.push(generateSmartExample(tool.name, inputSchema, tool.metadata?.description));
|
|
3139
3366
|
}
|
|
3140
3367
|
return result.slice(0, 5);
|
|
@@ -3223,7 +3450,11 @@ var runtimeErrorPayloadSchema = import_lazy_zod7.z.object({
|
|
|
3223
3450
|
var toolErrorPayloadSchema = import_lazy_zod7.z.object({
|
|
3224
3451
|
source: import_lazy_zod7.z.literal("tool"),
|
|
3225
3452
|
toolName: import_lazy_zod7.z.string(),
|
|
3226
|
-
|
|
3453
|
+
/**
|
|
3454
|
+
* @deprecated Never set: the sandbox resolves sidecar references in a call's arguments before
|
|
3455
|
+
* the tool sees them, so they may hold data the script itself never had.
|
|
3456
|
+
*/
|
|
3457
|
+
toolInput: import_lazy_zod7.z.unknown().optional(),
|
|
3227
3458
|
message: import_lazy_zod7.z.string(),
|
|
3228
3459
|
code: import_lazy_zod7.z.string().optional(),
|
|
3229
3460
|
/** @deprecated Never set: the enclave's error data is not sanitized for clients. */
|
|
@@ -3470,10 +3701,10 @@ var ExecuteTool = class extends import_sdk8.ToolContext {
|
|
|
3470
3701
|
error: {
|
|
3471
3702
|
source: "tool",
|
|
3472
3703
|
toolName: error.toolName,
|
|
3473
|
-
toolInput: error.toolInput,
|
|
3474
3704
|
message: toClientErrorMessage(error.message),
|
|
3475
3705
|
code: error.code
|
|
3476
|
-
// No `details`: the enclave's error data is not sanitized for clients.
|
|
3706
|
+
// No `details`: the enclave's error data is not sanitized for clients. No `toolInput`:
|
|
3707
|
+
// the arguments the tool saw may hold sidecar-resolved data the script never had.
|
|
3477
3708
|
}
|
|
3478
3709
|
};
|
|
3479
3710
|
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@frontmcp/plugin-codecall",
|
|
3
|
-
"version": "1.8.
|
|
3
|
+
"version": "1.8.6",
|
|
4
4
|
"description": "CodeCall plugin for FrontMCP - AgentScript-based meta-tools for orchestrating MCP tools",
|
|
5
5
|
"author": "AgentFront <info@agentfront.dev>",
|
|
6
6
|
"license": "Apache-2.0",
|
|
@@ -48,14 +48,16 @@
|
|
|
48
48
|
}
|
|
49
49
|
},
|
|
50
50
|
"dependencies": {
|
|
51
|
+
"@enclave-vm/ast": "^2.15.3",
|
|
51
52
|
"@enclave-vm/core": "^2.15.3",
|
|
52
|
-
"@frontmcp/protocol": "1.8.
|
|
53
|
-
"@frontmcp/sdk": "1.8.
|
|
53
|
+
"@frontmcp/protocol": "1.8.6",
|
|
54
|
+
"@frontmcp/sdk": "1.8.6",
|
|
55
|
+
"acorn": "^8.15.0",
|
|
54
56
|
"vectoriadb": "^2.3.2"
|
|
55
57
|
},
|
|
56
58
|
"peerDependencies": {
|
|
57
|
-
"@frontmcp/lazy-zod": "1.8.
|
|
58
|
-
"@frontmcp/plugin-cache": "1.8.
|
|
59
|
+
"@frontmcp/lazy-zod": "1.8.6",
|
|
60
|
+
"@frontmcp/plugin-cache": "1.8.6"
|
|
59
61
|
},
|
|
60
62
|
"devDependencies": {
|
|
61
63
|
"reflect-metadata": "^0.2.2"
|
|
@@ -12,7 +12,6 @@ export interface EnclaveExecutionResult {
|
|
|
12
12
|
stack?: string;
|
|
13
13
|
code?: string;
|
|
14
14
|
toolName?: string;
|
|
15
|
-
toolInput?: unknown;
|
|
16
15
|
details?: unknown;
|
|
17
16
|
/** For a script that doesn't parse (`code: 'SYNTAX_ERROR'`): where, in the script's own lines. */
|
|
18
17
|
location?: {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"enclave.service.d.ts","sourceRoot":"","sources":["../../src/services/enclave.service.ts"],"names":[],"mappings":"AAYA,OAAO,KAAK,EAAE,qBAAqB,EAA6B,MAAM,oBAAoB,CAAC;AAE3F,OAAO,KAAK,cAAc,MAAM,+BAA+B,CAAC;
|
|
1
|
+
{"version":3,"file":"enclave.service.d.ts","sourceRoot":"","sources":["../../src/services/enclave.service.ts"],"names":[],"mappings":"AAYA,OAAO,KAAK,EAAE,qBAAqB,EAA6B,MAAM,oBAAoB,CAAC;AAE3F,OAAO,KAAK,cAAc,MAAM,+BAA+B,CAAC;AAIhE;;GAEG;AACH,MAAM,WAAW,sBAAsB;IACrC,OAAO,EAAE,OAAO,CAAC;IACjB,MAAM,CAAC,EAAE,OAAO,CAAC;IACjB,KAAK,CAAC,EAAE;QACN,OAAO,EAAE,MAAM,CAAC;QAChB,IAAI,EAAE,MAAM,CAAC;QACb,KAAK,CAAC,EAAE,MAAM,CAAC;QACf,IAAI,CAAC,EAAE,MAAM,CAAC;QACd,QAAQ,CAAC,EAAE,MAAM,CAAC;QAClB,OAAO,CAAC,EAAE,OAAO,CAAC;QAClB,kGAAkG;QAClG,QAAQ,CAAC,EAAE;YAAE,IAAI,EAAE,MAAM,CAAC;YAAC,MAAM,EAAE,MAAM,CAAA;SAAE,CAAC;QAC5C;;;;;WAKG;QACH,eAAe,CAAC,EAAE,MAAM,EAAE,CAAC;QAC3B,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC;KACxB,CAAC;IACF,IAAI,EAAE,MAAM,EAAE,CAAC;IACf,QAAQ,EAAE,OAAO,CAAC;IAClB,KAAK,CAAC,EAAE;QACN,QAAQ,EAAE,MAAM,CAAC;QACjB,aAAa,EAAE,MAAM,CAAC;QACtB,cAAc,EAAE,MAAM,CAAC;KACxB,CAAC;CACH;AAkDD;;;;;;;;GAQG;AACH;;GAEG;AACH,qBAAa,mBAAoB,SAAQ,KAAK;IAC5C,QAAQ,CAAC,IAAI,sBAAsB;IACnC,QAAQ,CAAC,YAAY,EAAE,MAAM,CAAC;IAC9B,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAC;gBAEf,YAAY,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM;CASpD;AAOD,MAAM,CAAC,OAAO,OAAO,cAAc;IACjC,OAAO,CAAC,QAAQ,CAAC,SAAS,CAA4B;IACtD,OAAO,CAAC,QAAQ,CAAC,cAAc,CAAyB;gBAE5C,MAAM,EAAE,cAAc;IAOlC;;;;;;;OAOG;IACG,OAAO,CAAC,IAAI,EAAE,MAAM,EAAE,WAAW,EAAE,qBAAqB,GAAG,OAAO,CAAC,sBAAsB,CAAC;IAwGhG;;OAEG;IACH,OAAO,CAAC,gBAAgB;CAyFzB"}
|
package/tools/describe.tool.d.ts
CHANGED
|
@@ -28,7 +28,9 @@ export default class DescribeTool extends ToolContext {
|
|
|
28
28
|
*
|
|
29
29
|
* Priority:
|
|
30
30
|
* 1. User-provided examples from @Tool decorator metadata (up to 5)
|
|
31
|
-
* 2.
|
|
31
|
+
* 2. Without any, one smart intent-based example built from the input schema. It is never added
|
|
32
|
+
* next to the tool's own examples: those show how the tool is called, and a generated one
|
|
33
|
+
* only guesses (#647).
|
|
32
34
|
* 3. Returns at least 1 example
|
|
33
35
|
*/
|
|
34
36
|
private generateExamples;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"describe.tool.d.ts","sourceRoot":"","sources":["../../src/tools/describe.tool.ts"],"names":[],"mappings":"AAEA,OAAO,EAAwB,WAAW,EAAkB,MAAM,eAAe,CAAC;AAMlF,OAAO,EAIL,KAAK,iBAAiB,EACtB,KAAK,kBAAkB,EACxB,MAAM,mBAAmB,CAAC;AAuB3B,MAAM,CAAC,OAAO,OAAO,YAAa,SAAQ,WAAW;IAC7C,OAAO,CAAC,KAAK,EAAE,iBAAiB,GAAG,OAAO,CAAC,kBAAkB,CAAC;IAkEpE;;;;;;;;OAQG;IACH,OAAO,CAAC,cAAc;IAuBtB;;;;;OAKG;IACH,OAAO,CAAC,YAAY;IAkDpB;;OAEG;IACH,OAAO,CAAC,YAAY;IA6BpB
|
|
1
|
+
{"version":3,"file":"describe.tool.d.ts","sourceRoot":"","sources":["../../src/tools/describe.tool.ts"],"names":[],"mappings":"AAEA,OAAO,EAAwB,WAAW,EAAkB,MAAM,eAAe,CAAC;AAMlF,OAAO,EAIL,KAAK,iBAAiB,EACtB,KAAK,kBAAkB,EACxB,MAAM,mBAAmB,CAAC;AAuB3B,MAAM,CAAC,OAAO,OAAO,YAAa,SAAQ,WAAW;IAC7C,OAAO,CAAC,KAAK,EAAE,iBAAiB,GAAG,OAAO,CAAC,kBAAkB,CAAC;IAkEpE;;;;;;;;OAQG;IACH,OAAO,CAAC,cAAc;IAuBtB;;;;;OAKG;IACH,OAAO,CAAC,YAAY;IAkDpB;;OAEG;IACH,OAAO,CAAC,YAAY;IA6BpB;;;;;;;;;OASG;IACH,OAAO,CAAC,gBAAgB;CAyBzB"}
|
|
@@ -44,7 +44,7 @@ export declare const codeCallToolErrorResultSchema: import("@frontmcp/lazy-zod")
|
|
|
44
44
|
error: import("@frontmcp/lazy-zod").ZodObject<{
|
|
45
45
|
source: import("@frontmcp/lazy-zod").ZodLiteral<"tool">;
|
|
46
46
|
toolName: import("@frontmcp/lazy-zod").ZodString;
|
|
47
|
-
toolInput: import("@frontmcp/lazy-zod").ZodUnknown
|
|
47
|
+
toolInput: import("@frontmcp/lazy-zod").ZodOptional<import("@frontmcp/lazy-zod").ZodUnknown>;
|
|
48
48
|
message: import("@frontmcp/lazy-zod").ZodString;
|
|
49
49
|
code: import("@frontmcp/lazy-zod").ZodOptional<import("@frontmcp/lazy-zod").ZodString>;
|
|
50
50
|
details: import("@frontmcp/lazy-zod").ZodOptional<import("@frontmcp/lazy-zod").ZodUnknown>;
|
|
@@ -91,7 +91,7 @@ export declare const executeToolOutputSchema: import("@frontmcp/lazy-zod").ZodDi
|
|
|
91
91
|
error: import("@frontmcp/lazy-zod").ZodObject<{
|
|
92
92
|
source: import("@frontmcp/lazy-zod").ZodLiteral<"tool">;
|
|
93
93
|
toolName: import("@frontmcp/lazy-zod").ZodString;
|
|
94
|
-
toolInput: import("@frontmcp/lazy-zod").ZodUnknown
|
|
94
|
+
toolInput: import("@frontmcp/lazy-zod").ZodOptional<import("@frontmcp/lazy-zod").ZodUnknown>;
|
|
95
95
|
message: import("@frontmcp/lazy-zod").ZodString;
|
|
96
96
|
code: import("@frontmcp/lazy-zod").ZodOptional<import("@frontmcp/lazy-zod").ZodString>;
|
|
97
97
|
details: import("@frontmcp/lazy-zod").ZodOptional<import("@frontmcp/lazy-zod").ZodUnknown>;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"execute.schema.d.ts","sourceRoot":"","sources":["../../src/tools/execute.schema.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,CAAC,EAAE,MAAM,oBAAoB,CAAC;AAKvC,eAAO,MAAM,sBAAsB,o7BAoBe,CAAC;AAEnD,eAAO,MAAM,sBAAsB;;;CAclC,CAAC;AAEF,MAAM,MAAM,gBAAgB,GAAG,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,SAAS,CAAC,OAAO,sBAAsB,CAAC,CAAC,CAAC;
|
|
1
|
+
{"version":3,"file":"execute.schema.d.ts","sourceRoot":"","sources":["../../src/tools/execute.schema.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,CAAC,EAAE,MAAM,oBAAoB,CAAC;AAKvC,eAAO,MAAM,sBAAsB,o7BAoBe,CAAC;AAEnD,eAAO,MAAM,sBAAsB;;;CAclC,CAAC;AAEF,MAAM,MAAM,gBAAgB,GAAG,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,SAAS,CAAC,OAAO,sBAAsB,CAAC,CAAC,CAAC;AAkDnF;;GAEG;AACH,eAAO,MAAM,sBAAsB;;;;gCAIjC,CAAC;AAEH,eAAO,MAAM,+BAA+B;;;;;;;;;gCAG1C,CAAC;AAEH,eAAO,MAAM,iCAAiC;;;;;;gCAG5C,CAAC;AAEH,eAAO,MAAM,gCAAgC;;;;;;;;gCAG3C,CAAC;AAEH,eAAO,MAAM,6BAA6B;;;;;;;;;;gCAGxC,CAAC;AAEH,eAAO,MAAM,2BAA2B;;;;;gCAGtC,CAAC;AAEH;;GAEG;AACH,eAAO,MAAM,uBAAuB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;4CAOlC,CAAC;AAEH;;;GAGG;AACH,MAAM,MAAM,gBAAgB,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,sBAAsB,CAAC,CAAC;AACtE,MAAM,MAAM,yBAAyB,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,+BAA+B,CAAC,CAAC;AACxF,MAAM,MAAM,2BAA2B,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,iCAAiC,CAAC,CAAC;AAC5F,MAAM,MAAM,0BAA0B,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,gCAAgC,CAAC,CAAC;AAC1F,MAAM,MAAM,uBAAuB,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,6BAA6B,CAAC,CAAC;AACpF,MAAM,MAAM,qBAAqB,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,2BAA2B,CAAC,CAAC;AAEhF,MAAM,MAAM,qBAAqB,GAC7B,gBAAgB,GAChB,yBAAyB,GACzB,2BAA2B,GAC3B,0BAA0B,GAC1B,uBAAuB,GACvB,qBAAqB,CAAC"}
|
|
@@ -46,13 +46,14 @@ export declare function hasFilterParams(schema?: JsonSchema): boolean;
|
|
|
46
46
|
*/
|
|
47
47
|
export declare function getFilterProperties(schema?: JsonSchema): string[];
|
|
48
48
|
/**
|
|
49
|
-
* Generate a pagination example for a tool
|
|
49
|
+
* Generate a pagination example for a tool, paging with the pagination properties its schema
|
|
50
|
+
* declares (two pages when it takes `limit` and `offset`, one otherwise).
|
|
50
51
|
*/
|
|
51
|
-
export declare function generatePaginationExample(toolName: string): ToolUsageExample;
|
|
52
|
+
export declare function generatePaginationExample(toolName: string, inputSchema?: JsonSchema): ToolUsageExample;
|
|
52
53
|
/**
|
|
53
|
-
* Generate a filter example for a tool.
|
|
54
|
+
* Generate a filter example for a tool, with a value the property's schema accepts.
|
|
54
55
|
*/
|
|
55
|
-
export declare function generateFilterExample(toolName: string, filterProp: string): ToolUsageExample;
|
|
56
|
+
export declare function generateFilterExample(toolName: string, filterProp: string, inputSchema?: JsonSchema): ToolUsageExample;
|
|
56
57
|
/**
|
|
57
58
|
* Generate a create example for a tool.
|
|
58
59
|
* Shows required parameters with contextual sample values.
|
|
@@ -63,7 +64,8 @@ export declare function generateCreateExample(toolName: string, inputSchema?: Js
|
|
|
63
64
|
*/
|
|
64
65
|
export declare function generateGetExample(toolName: string, inputSchema?: JsonSchema): ToolUsageExample;
|
|
65
66
|
/**
|
|
66
|
-
* Generate a list example for a tool.
|
|
67
|
+
* Generate a list example for a tool: the required properties, or `{}` when it has none. Tools
|
|
68
|
+
* that declare pagination properties get `generatePaginationExample` instead.
|
|
67
69
|
*/
|
|
68
70
|
export declare function generateListExample(toolName: string, inputSchema?: JsonSchema): ToolUsageExample;
|
|
69
71
|
/**
|
|
@@ -76,6 +78,10 @@ export declare function generateUpdateExample(toolName: string, inputSchema?: Js
|
|
|
76
78
|
export declare function generateDeleteExample(toolName: string, inputSchema?: JsonSchema): ToolUsageExample;
|
|
77
79
|
/**
|
|
78
80
|
* Generate a search example for a tool.
|
|
81
|
+
*
|
|
82
|
+
* Searches by the tool's query-like property, else by its first filter property (`status`, `type`,
|
|
83
|
+
* ...), with the required properties alongside. Never a `query` the schema does not declare: a tool
|
|
84
|
+
* searched by `status` and `priority` was shown `callTool('<tool>', { query: 'search term' })`.
|
|
79
85
|
*/
|
|
80
86
|
export declare function generateSearchExample(toolName: string, inputSchema?: JsonSchema): ToolUsageExample;
|
|
81
87
|
/**
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"describe.utils.d.ts","sourceRoot":"","sources":["../../src/utils/describe.utils.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,oBAAoB,CAAC;AAErD,mCAAmC;AACnC,KAAK,UAAU,GAAG,UAAU,CAAC,UAAU,CAAC;AAExC;;GAEG;AACH,MAAM,WAAW,gBAAgB;IAC/B,WAAW,EAAE,MAAM,CAAC;IACpB,IAAI,EAAE,MAAM,CAAC;CACd;AAED;;GAEG;AACH,MAAM,MAAM,UAAU,GAAG,QAAQ,GAAG,MAAM,GAAG,KAAK,GAAG,QAAQ,GAAG,QAAQ,GAAG,QAAQ,GAAG,QAAQ,GAAG,SAAS,CAAC;AAiB3G;;;GAGG;AACH,wBAAgB,gBAAgB,CAAC,QAAQ,EAAE,MAAM,EAAE,WAAW,CAAC,EAAE,MAAM,GAAG,UAAU,CAwBnF;AAED;;;;;;GAMG;AACH,wBAAgB,qBAAqB,CAAC,QAAQ,EAAE,MAAM,EAAE,WAAW,CAAC,EAAE,UAAU,EAAE,YAAY,CAAC,EAAE,UAAU,GAAG,MAAM,CAKnH;AAkFD;;GAEG;AACH,wBAAgB,2BAA2B,CACzC,MAAM,EAAE,UAAU,GAAG,SAAS,GAAG,IAAI,EACrC,SAAS,EAAE,OAAO,GAAG,QAAQ,GAC5B,MAAM,CAkCR;AAED;;GAEG;AACH,wBAAgB,oBAAoB,CAAC,QAAQ,EAAE,MAAM,EAAE,WAAW,CAAC,EAAE,UAAU,GAAG,gBAAgB,CASjG;
|
|
1
|
+
{"version":3,"file":"describe.utils.d.ts","sourceRoot":"","sources":["../../src/utils/describe.utils.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,oBAAoB,CAAC;AAErD,mCAAmC;AACnC,KAAK,UAAU,GAAG,UAAU,CAAC,UAAU,CAAC;AAExC;;GAEG;AACH,MAAM,WAAW,gBAAgB;IAC/B,WAAW,EAAE,MAAM,CAAC;IACpB,IAAI,EAAE,MAAM,CAAC;CACd;AAED;;GAEG;AACH,MAAM,MAAM,UAAU,GAAG,QAAQ,GAAG,MAAM,GAAG,KAAK,GAAG,QAAQ,GAAG,QAAQ,GAAG,QAAQ,GAAG,QAAQ,GAAG,SAAS,CAAC;AAiB3G;;;GAGG;AACH,wBAAgB,gBAAgB,CAAC,QAAQ,EAAE,MAAM,EAAE,WAAW,CAAC,EAAE,MAAM,GAAG,UAAU,CAwBnF;AAED;;;;;;GAMG;AACH,wBAAgB,qBAAqB,CAAC,QAAQ,EAAE,MAAM,EAAE,WAAW,CAAC,EAAE,UAAU,EAAE,YAAY,CAAC,EAAE,UAAU,GAAG,MAAM,CAKnH;AAkFD;;GAEG;AACH,wBAAgB,2BAA2B,CACzC,MAAM,EAAE,UAAU,GAAG,SAAS,GAAG,IAAI,EACrC,SAAS,EAAE,OAAO,GAAG,QAAQ,GAC5B,MAAM,CAkCR;AAED;;GAEG;AACH,wBAAgB,oBAAoB,CAAC,QAAQ,EAAE,MAAM,EAAE,WAAW,CAAC,EAAE,UAAU,GAAG,gBAAgB,CASjG;AA+ID;;GAEG;AACH,wBAAgB,mBAAmB,CAAC,MAAM,CAAC,EAAE,UAAU,GAAG,OAAO,CAMhE;AA0CD;;GAEG;AACH,wBAAgB,eAAe,CAAC,MAAM,CAAC,EAAE,UAAU,GAAG,OAAO,CAe5D;AAED;;GAEG;AACH,wBAAgB,mBAAmB,CAAC,MAAM,CAAC,EAAE,UAAU,GAAG,MAAM,EAAE,CAcjE;AAED;;;GAGG;AACH,wBAAgB,yBAAyB,CAAC,QAAQ,EAAE,MAAM,EAAE,WAAW,CAAC,EAAE,UAAU,GAAG,gBAAgB,CA+CtG;AAED;;GAEG;AACH,wBAAgB,qBAAqB,CACnC,QAAQ,EAAE,MAAM,EAChB,UAAU,EAAE,MAAM,EAClB,WAAW,CAAC,EAAE,UAAU,GACvB,gBAAgB,CASlB;AAgBD;;;GAGG;AACH,wBAAgB,qBAAqB,CAAC,QAAQ,EAAE,MAAM,EAAE,WAAW,CAAC,EAAE,UAAU,GAAG,gBAAgB,CAUlG;AAYD;;GAEG;AACH,wBAAgB,kBAAkB,CAAC,QAAQ,EAAE,MAAM,EAAE,WAAW,CAAC,EAAE,UAAU,GAAG,gBAAgB,CAqB/F;AAED;;;GAGG;AACH,wBAAgB,mBAAmB,CAAC,QAAQ,EAAE,MAAM,EAAE,WAAW,CAAC,EAAE,UAAU,GAAG,gBAAgB,CAQhG;AAED;;GAEG;AACH,wBAAgB,qBAAqB,CAAC,QAAQ,EAAE,MAAM,EAAE,WAAW,CAAC,EAAE,UAAU,GAAG,gBAAgB,CA2BlG;AAED;;GAEG;AACH,wBAAgB,qBAAqB,CAAC,QAAQ,EAAE,MAAM,EAAE,WAAW,CAAC,EAAE,UAAU,GAAG,gBAAgB,CAoBlG;AAED;;;;;;GAMG;AACH,wBAAgB,qBAAqB,CAAC,QAAQ,EAAE,MAAM,EAAE,WAAW,CAAC,EAAE,UAAU,GAAG,gBAAgB,CA8BlG;AA2ED;;;GAGG;AACH,wBAAgB,oBAAoB,CAClC,QAAQ,EAAE,MAAM,EAChB,WAAW,CAAC,EAAE,UAAU,EACxB,WAAW,CAAC,EAAE,MAAM,GACnB,gBAAgB,CAuBlB"}
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* A function from a line of the code the enclave validated (for this script) to the script's own
|
|
3
|
+
* line, or `undefined` for a line that is none of the script's (the wrapper, a line the loop
|
|
4
|
+
* transform added) or a script that can't be parsed.
|
|
5
|
+
*
|
|
6
|
+
* @param script The script as the caller sent it
|
|
7
|
+
*/
|
|
8
|
+
export declare function validatedLineMapper(script: string): (printedLine: number) => number | undefined;
|
|
9
|
+
/**
|
|
10
|
+
* `message` with the lines its issues name mapped back to the script's own lines. A line that is
|
|
11
|
+
* none of the script's is dropped rather than left pointing at the wrong line.
|
|
12
|
+
*/
|
|
13
|
+
export declare function withScriptLines(message: string, script: string): string;
|
|
14
|
+
//# sourceMappingURL=script-lines.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"script-lines.d.ts","sourceRoot":"","sources":["../../src/utils/script-lines.ts"],"names":[],"mappings":"AA4IA;;;;;;GAMG;AACH,wBAAgB,mBAAmB,CAAC,MAAM,EAAE,MAAM,GAAG,CAAC,WAAW,EAAE,MAAM,KAAK,MAAM,GAAG,SAAS,CAmB/F;AAKD;;;GAGG;AACH,wBAAgB,eAAe,CAAC,OAAO,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,GAAG,MAAM,CAOvE"}
|