@frontmcp/plugin-codecall 1.8.5 → 1.8.7
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 +139 -29
- package/esm/package.json +5 -5
- package/index.js +139 -29
- package/package.json +5 -5
- package/tools/describe.tool.d.ts +3 -1
- package/tools/describe.tool.d.ts.map +1 -1
- package/utils/describe.utils.d.ts +11 -5
- package/utils/describe.utils.d.ts.map +1 -1
package/esm/index.mjs
CHANGED
|
@@ -2768,6 +2768,43 @@ function generateSampleParams(schema) {
|
|
|
2768
2768
|
}
|
|
2769
2769
|
return Object.keys(params).length > 0 ? params : null;
|
|
2770
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
|
+
}
|
|
2771
2808
|
function getSampleValue(schema, key) {
|
|
2772
2809
|
if (schema.default !== void 0) {
|
|
2773
2810
|
return schema.default;
|
|
@@ -2781,11 +2818,11 @@ function getSampleValue(schema, key) {
|
|
|
2781
2818
|
const type = Array.isArray(schema.type) ? schema.type[0] : schema.type;
|
|
2782
2819
|
switch (type) {
|
|
2783
2820
|
case "string":
|
|
2784
|
-
if (key.toLowerCase().includes("id")) return "abc123";
|
|
2785
|
-
if (key.toLowerCase().includes("email")) return "user@example.com";
|
|
2786
|
-
if (key.toLowerCase().includes("name")) return "Example";
|
|
2787
|
-
if (key.toLowerCase().includes("url")) return "https://example.com";
|
|
2788
|
-
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");
|
|
2789
2826
|
case "number":
|
|
2790
2827
|
case "integer":
|
|
2791
2828
|
if (key.toLowerCase().includes("limit")) return 10;
|
|
@@ -2802,24 +2839,88 @@ function getSampleValue(schema, key) {
|
|
|
2802
2839
|
return null;
|
|
2803
2840
|
}
|
|
2804
2841
|
}
|
|
2842
|
+
var PAGINATION_PROPERTIES = ["limit", "offset", "page", "pagesize", "cursor"];
|
|
2843
|
+
function isPaginationProperty(name) {
|
|
2844
|
+
return PAGINATION_PROPERTIES.includes(name.toLowerCase());
|
|
2845
|
+
}
|
|
2805
2846
|
function hasPaginationParams(schema) {
|
|
2806
2847
|
if (!schema || schema.type !== "object" || !schema.properties) {
|
|
2807
2848
|
return false;
|
|
2808
2849
|
}
|
|
2809
|
-
|
|
2810
|
-
return props.some((p) => ["limit", "offset", "page", "pageSize", "cursor"].includes(p.toLowerCase()));
|
|
2850
|
+
return Object.keys(schema.properties).some(isPaginationProperty);
|
|
2811
2851
|
}
|
|
2812
|
-
function
|
|
2813
|
-
|
|
2814
|
-
|
|
2815
|
-
|
|
2816
|
-
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)});
|
|
2817
2905
|
|
|
2818
2906
|
// Fetch second page
|
|
2819
|
-
const page2 = await callTool('${toolName}', {
|
|
2907
|
+
const page2 = await callTool('${toolName}', ${formatExampleArgs(secondPage)});
|
|
2820
2908
|
|
|
2821
2909
|
// Combine results
|
|
2822
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;`
|
|
2823
2924
|
};
|
|
2824
2925
|
}
|
|
2825
2926
|
function extractEntityName(toolName) {
|
|
@@ -2837,13 +2938,18 @@ function generateCreateExample(toolName, inputSchema) {
|
|
|
2837
2938
|
return result;`
|
|
2838
2939
|
};
|
|
2839
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
|
+
}
|
|
2840
2946
|
function generateGetExample(toolName, inputSchema) {
|
|
2841
2947
|
const entity = extractEntityName(toolName);
|
|
2842
2948
|
const idParam = findIdParameter(inputSchema);
|
|
2843
2949
|
if (idParam) {
|
|
2844
2950
|
return {
|
|
2845
2951
|
description: `Get ${entity} by ${idParam}`,
|
|
2846
|
-
code: `const ${entity} = await callTool('${toolName}', {
|
|
2952
|
+
code: `const ${entity} = await callTool('${toolName}', ${formatInlineArgs(idArgs(inputSchema, idParam))});
|
|
2847
2953
|
return ${entity};`
|
|
2848
2954
|
};
|
|
2849
2955
|
}
|
|
@@ -2859,7 +2965,7 @@ function generateListExample(toolName, inputSchema) {
|
|
|
2859
2965
|
const entity = extractEntityName(toolName);
|
|
2860
2966
|
return {
|
|
2861
2967
|
description: `List all ${entity}s`,
|
|
2862
|
-
code: `const result = await callTool('${toolName}', {});
|
|
2968
|
+
code: `const result = await callTool('${toolName}', ${formatExampleArgs(buildExampleArgs(inputSchema, []))});
|
|
2863
2969
|
return result.items || result;`
|
|
2864
2970
|
};
|
|
2865
2971
|
}
|
|
@@ -2869,10 +2975,11 @@ function generateUpdateExample(toolName, inputSchema) {
|
|
|
2869
2975
|
const updateFields = generateUpdateFields(inputSchema);
|
|
2870
2976
|
const fieldsStr = updateFields ? JSON.stringify(updateFields, null, 2).replace(/\n/g, "\n ") : "{ /* fields to update */ }";
|
|
2871
2977
|
if (idParam) {
|
|
2978
|
+
const identifiers = formatInlineArgs(idArgs(inputSchema, idParam)).slice(2, -2);
|
|
2872
2979
|
return {
|
|
2873
2980
|
description: `Update ${entity} by ${idParam}`,
|
|
2874
2981
|
code: `const updated = await callTool('${toolName}', {
|
|
2875
|
-
${
|
|
2982
|
+
${identifiers},
|
|
2876
2983
|
...${fieldsStr}
|
|
2877
2984
|
});
|
|
2878
2985
|
return updated;`
|
|
@@ -2890,7 +2997,7 @@ function generateDeleteExample(toolName, inputSchema) {
|
|
|
2890
2997
|
if (idParam) {
|
|
2891
2998
|
return {
|
|
2892
2999
|
description: `Delete ${entity} by ${idParam}`,
|
|
2893
|
-
code: `const result = await callTool('${toolName}', {
|
|
3000
|
+
code: `const result = await callTool('${toolName}', ${formatInlineArgs(idArgs(inputSchema, idParam))});
|
|
2894
3001
|
return result;`
|
|
2895
3002
|
};
|
|
2896
3003
|
}
|
|
@@ -2904,17 +3011,18 @@ return result;`
|
|
|
2904
3011
|
}
|
|
2905
3012
|
function generateSearchExample(toolName, inputSchema) {
|
|
2906
3013
|
const entity = extractEntityName(toolName);
|
|
2907
|
-
const
|
|
2908
|
-
|
|
2909
|
-
|
|
2910
|
-
|
|
2911
|
-
|
|
2912
|
-
|
|
2913
|
-
|
|
2914
|
-
|
|
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, []);
|
|
2915
3023
|
return {
|
|
2916
3024
|
description: `Search for ${entity}s`,
|
|
2917
|
-
code: `const results = await callTool('${toolName}', {
|
|
3025
|
+
code: `const results = await callTool('${toolName}', ${formatExampleArgs(args)});
|
|
2918
3026
|
return results.items || results;`
|
|
2919
3027
|
};
|
|
2920
3028
|
}
|
|
@@ -2971,7 +3079,7 @@ function generateSmartExample(toolName, inputSchema, description) {
|
|
|
2971
3079
|
case "get":
|
|
2972
3080
|
return generateGetExample(toolName, inputSchema);
|
|
2973
3081
|
case "list":
|
|
2974
|
-
return hasPaginationParams(inputSchema) ? generatePaginationExample(toolName) : generateListExample(toolName, inputSchema);
|
|
3082
|
+
return hasPaginationParams(inputSchema) ? generatePaginationExample(toolName, inputSchema) : generateListExample(toolName, inputSchema);
|
|
2975
3083
|
case "update":
|
|
2976
3084
|
return generateUpdateExample(toolName, inputSchema);
|
|
2977
3085
|
case "delete":
|
|
@@ -3199,7 +3307,9 @@ var DescribeTool = class extends ToolContext4 {
|
|
|
3199
3307
|
*
|
|
3200
3308
|
* Priority:
|
|
3201
3309
|
* 1. User-provided examples from @Tool decorator metadata (up to 5)
|
|
3202
|
-
* 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).
|
|
3203
3313
|
* 3. Returns at least 1 example
|
|
3204
3314
|
*/
|
|
3205
3315
|
generateExamples(tool, inputSchema) {
|
|
@@ -3214,7 +3324,7 @@ return result;`
|
|
|
3214
3324
|
});
|
|
3215
3325
|
}
|
|
3216
3326
|
}
|
|
3217
|
-
if (result.length
|
|
3327
|
+
if (result.length === 0) {
|
|
3218
3328
|
result.push(generateSmartExample(tool.name, inputSchema, tool.metadata?.description));
|
|
3219
3329
|
}
|
|
3220
3330
|
return result.slice(0, 5);
|
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.7",
|
|
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",
|
|
@@ -50,14 +50,14 @@
|
|
|
50
50
|
"dependencies": {
|
|
51
51
|
"@enclave-vm/ast": "^2.15.3",
|
|
52
52
|
"@enclave-vm/core": "^2.15.3",
|
|
53
|
-
"@frontmcp/protocol": "1.8.
|
|
54
|
-
"@frontmcp/sdk": "1.8.
|
|
53
|
+
"@frontmcp/protocol": "1.8.7",
|
|
54
|
+
"@frontmcp/sdk": "1.8.7",
|
|
55
55
|
"acorn": "^8.15.0",
|
|
56
56
|
"vectoriadb": "^2.3.2"
|
|
57
57
|
},
|
|
58
58
|
"peerDependencies": {
|
|
59
|
-
"@frontmcp/lazy-zod": "1.8.
|
|
60
|
-
"@frontmcp/plugin-cache": "1.8.
|
|
59
|
+
"@frontmcp/lazy-zod": "1.8.7",
|
|
60
|
+
"@frontmcp/plugin-cache": "1.8.7"
|
|
61
61
|
},
|
|
62
62
|
"devDependencies": {
|
|
63
63
|
"reflect-metadata": "^0.2.2"
|
package/index.js
CHANGED
|
@@ -2805,6 +2805,43 @@ function generateSampleParams(schema) {
|
|
|
2805
2805
|
}
|
|
2806
2806
|
return Object.keys(params).length > 0 ? params : null;
|
|
2807
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
|
+
}
|
|
2808
2845
|
function getSampleValue(schema, key) {
|
|
2809
2846
|
if (schema.default !== void 0) {
|
|
2810
2847
|
return schema.default;
|
|
@@ -2818,11 +2855,11 @@ function getSampleValue(schema, key) {
|
|
|
2818
2855
|
const type = Array.isArray(schema.type) ? schema.type[0] : schema.type;
|
|
2819
2856
|
switch (type) {
|
|
2820
2857
|
case "string":
|
|
2821
|
-
if (key.toLowerCase().includes("id")) return "abc123";
|
|
2822
|
-
if (key.toLowerCase().includes("email")) return "user@example.com";
|
|
2823
|
-
if (key.toLowerCase().includes("name")) return "Example";
|
|
2824
|
-
if (key.toLowerCase().includes("url")) return "https://example.com";
|
|
2825
|
-
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");
|
|
2826
2863
|
case "number":
|
|
2827
2864
|
case "integer":
|
|
2828
2865
|
if (key.toLowerCase().includes("limit")) return 10;
|
|
@@ -2839,24 +2876,88 @@ function getSampleValue(schema, key) {
|
|
|
2839
2876
|
return null;
|
|
2840
2877
|
}
|
|
2841
2878
|
}
|
|
2879
|
+
var PAGINATION_PROPERTIES = ["limit", "offset", "page", "pagesize", "cursor"];
|
|
2880
|
+
function isPaginationProperty(name) {
|
|
2881
|
+
return PAGINATION_PROPERTIES.includes(name.toLowerCase());
|
|
2882
|
+
}
|
|
2842
2883
|
function hasPaginationParams(schema) {
|
|
2843
2884
|
if (!schema || schema.type !== "object" || !schema.properties) {
|
|
2844
2885
|
return false;
|
|
2845
2886
|
}
|
|
2846
|
-
|
|
2847
|
-
return props.some((p) => ["limit", "offset", "page", "pageSize", "cursor"].includes(p.toLowerCase()));
|
|
2887
|
+
return Object.keys(schema.properties).some(isPaginationProperty);
|
|
2848
2888
|
}
|
|
2849
|
-
function
|
|
2850
|
-
|
|
2851
|
-
|
|
2852
|
-
|
|
2853
|
-
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)});
|
|
2854
2942
|
|
|
2855
2943
|
// Fetch second page
|
|
2856
|
-
const page2 = await callTool('${toolName}', {
|
|
2944
|
+
const page2 = await callTool('${toolName}', ${formatExampleArgs(secondPage)});
|
|
2857
2945
|
|
|
2858
2946
|
// Combine results
|
|
2859
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;`
|
|
2860
2961
|
};
|
|
2861
2962
|
}
|
|
2862
2963
|
function extractEntityName(toolName) {
|
|
@@ -2874,13 +2975,18 @@ function generateCreateExample(toolName, inputSchema) {
|
|
|
2874
2975
|
return result;`
|
|
2875
2976
|
};
|
|
2876
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
|
+
}
|
|
2877
2983
|
function generateGetExample(toolName, inputSchema) {
|
|
2878
2984
|
const entity = extractEntityName(toolName);
|
|
2879
2985
|
const idParam = findIdParameter(inputSchema);
|
|
2880
2986
|
if (idParam) {
|
|
2881
2987
|
return {
|
|
2882
2988
|
description: `Get ${entity} by ${idParam}`,
|
|
2883
|
-
code: `const ${entity} = await callTool('${toolName}', {
|
|
2989
|
+
code: `const ${entity} = await callTool('${toolName}', ${formatInlineArgs(idArgs(inputSchema, idParam))});
|
|
2884
2990
|
return ${entity};`
|
|
2885
2991
|
};
|
|
2886
2992
|
}
|
|
@@ -2896,7 +3002,7 @@ function generateListExample(toolName, inputSchema) {
|
|
|
2896
3002
|
const entity = extractEntityName(toolName);
|
|
2897
3003
|
return {
|
|
2898
3004
|
description: `List all ${entity}s`,
|
|
2899
|
-
code: `const result = await callTool('${toolName}', {});
|
|
3005
|
+
code: `const result = await callTool('${toolName}', ${formatExampleArgs(buildExampleArgs(inputSchema, []))});
|
|
2900
3006
|
return result.items || result;`
|
|
2901
3007
|
};
|
|
2902
3008
|
}
|
|
@@ -2906,10 +3012,11 @@ function generateUpdateExample(toolName, inputSchema) {
|
|
|
2906
3012
|
const updateFields = generateUpdateFields(inputSchema);
|
|
2907
3013
|
const fieldsStr = updateFields ? JSON.stringify(updateFields, null, 2).replace(/\n/g, "\n ") : "{ /* fields to update */ }";
|
|
2908
3014
|
if (idParam) {
|
|
3015
|
+
const identifiers = formatInlineArgs(idArgs(inputSchema, idParam)).slice(2, -2);
|
|
2909
3016
|
return {
|
|
2910
3017
|
description: `Update ${entity} by ${idParam}`,
|
|
2911
3018
|
code: `const updated = await callTool('${toolName}', {
|
|
2912
|
-
${
|
|
3019
|
+
${identifiers},
|
|
2913
3020
|
...${fieldsStr}
|
|
2914
3021
|
});
|
|
2915
3022
|
return updated;`
|
|
@@ -2927,7 +3034,7 @@ function generateDeleteExample(toolName, inputSchema) {
|
|
|
2927
3034
|
if (idParam) {
|
|
2928
3035
|
return {
|
|
2929
3036
|
description: `Delete ${entity} by ${idParam}`,
|
|
2930
|
-
code: `const result = await callTool('${toolName}', {
|
|
3037
|
+
code: `const result = await callTool('${toolName}', ${formatInlineArgs(idArgs(inputSchema, idParam))});
|
|
2931
3038
|
return result;`
|
|
2932
3039
|
};
|
|
2933
3040
|
}
|
|
@@ -2941,17 +3048,18 @@ return result;`
|
|
|
2941
3048
|
}
|
|
2942
3049
|
function generateSearchExample(toolName, inputSchema) {
|
|
2943
3050
|
const entity = extractEntityName(toolName);
|
|
2944
|
-
const
|
|
2945
|
-
|
|
2946
|
-
|
|
2947
|
-
|
|
2948
|
-
|
|
2949
|
-
|
|
2950
|
-
|
|
2951
|
-
|
|
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, []);
|
|
2952
3060
|
return {
|
|
2953
3061
|
description: `Search for ${entity}s`,
|
|
2954
|
-
code: `const results = await callTool('${toolName}', {
|
|
3062
|
+
code: `const results = await callTool('${toolName}', ${formatExampleArgs(args)});
|
|
2955
3063
|
return results.items || results;`
|
|
2956
3064
|
};
|
|
2957
3065
|
}
|
|
@@ -3008,7 +3116,7 @@ function generateSmartExample(toolName, inputSchema, description) {
|
|
|
3008
3116
|
case "get":
|
|
3009
3117
|
return generateGetExample(toolName, inputSchema);
|
|
3010
3118
|
case "list":
|
|
3011
|
-
return hasPaginationParams(inputSchema) ? generatePaginationExample(toolName) : generateListExample(toolName, inputSchema);
|
|
3119
|
+
return hasPaginationParams(inputSchema) ? generatePaginationExample(toolName, inputSchema) : generateListExample(toolName, inputSchema);
|
|
3012
3120
|
case "update":
|
|
3013
3121
|
return generateUpdateExample(toolName, inputSchema);
|
|
3014
3122
|
case "delete":
|
|
@@ -3236,7 +3344,9 @@ var DescribeTool = class extends import_sdk7.ToolContext {
|
|
|
3236
3344
|
*
|
|
3237
3345
|
* Priority:
|
|
3238
3346
|
* 1. User-provided examples from @Tool decorator metadata (up to 5)
|
|
3239
|
-
* 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).
|
|
3240
3350
|
* 3. Returns at least 1 example
|
|
3241
3351
|
*/
|
|
3242
3352
|
generateExamples(tool, inputSchema) {
|
|
@@ -3251,7 +3361,7 @@ return result;`
|
|
|
3251
3361
|
});
|
|
3252
3362
|
}
|
|
3253
3363
|
}
|
|
3254
|
-
if (result.length
|
|
3364
|
+
if (result.length === 0) {
|
|
3255
3365
|
result.push(generateSmartExample(tool.name, inputSchema, tool.metadata?.description));
|
|
3256
3366
|
}
|
|
3257
3367
|
return result.slice(0, 5);
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@frontmcp/plugin-codecall",
|
|
3
|
-
"version": "1.8.
|
|
3
|
+
"version": "1.8.7",
|
|
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",
|
|
@@ -50,14 +50,14 @@
|
|
|
50
50
|
"dependencies": {
|
|
51
51
|
"@enclave-vm/ast": "^2.15.3",
|
|
52
52
|
"@enclave-vm/core": "^2.15.3",
|
|
53
|
-
"@frontmcp/protocol": "1.8.
|
|
54
|
-
"@frontmcp/sdk": "1.8.
|
|
53
|
+
"@frontmcp/protocol": "1.8.7",
|
|
54
|
+
"@frontmcp/sdk": "1.8.7",
|
|
55
55
|
"acorn": "^8.15.0",
|
|
56
56
|
"vectoriadb": "^2.3.2"
|
|
57
57
|
},
|
|
58
58
|
"peerDependencies": {
|
|
59
|
-
"@frontmcp/lazy-zod": "1.8.
|
|
60
|
-
"@frontmcp/plugin-cache": "1.8.
|
|
59
|
+
"@frontmcp/lazy-zod": "1.8.7",
|
|
60
|
+
"@frontmcp/plugin-cache": "1.8.7"
|
|
61
61
|
},
|
|
62
62
|
"devDependencies": {
|
|
63
63
|
"reflect-metadata": "^0.2.2"
|
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"}
|
|
@@ -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"}
|