@frontmcp/plugin-codecall 1.3.0 → 1.4.1
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/codecall.plugin.d.ts +2 -2
- package/codecall.plugin.d.ts.map +1 -1
- package/codecall.symbol.d.ts +15 -2
- package/codecall.symbol.d.ts.map +1 -1
- package/esm/index.mjs +553 -182
- package/esm/package.json +9 -6
- package/index.js +566 -195
- package/package.json +9 -6
- package/services/enclave.service.d.ts +1 -1
- package/services/enclave.service.d.ts.map +1 -1
- package/tools/describe.tool.d.ts.map +1 -1
- package/tools/execute.tool.d.ts +1 -1
- package/tools/execute.tool.d.ts.map +1 -1
- package/tools/index.d.ts +2 -0
- package/tools/index.d.ts.map +1 -1
- package/tools/search-knowledge.schema.d.ts +35 -0
- package/tools/search-knowledge.schema.d.ts.map +1 -0
- package/tools/search-knowledge.tool.d.ts +6 -0
- package/tools/search-knowledge.tool.d.ts.map +1 -0
- package/tools/search-skills.schema.d.ts +40 -0
- package/tools/search-skills.schema.d.ts.map +1 -0
- package/tools/search-skills.tool.d.ts +6 -0
- package/tools/search-skills.tool.d.ts.map +1 -0
- package/utils/build-tool-namespaces.d.ts +47 -0
- package/utils/build-tool-namespaces.d.ts.map +1 -0
- package/utils/index.d.ts +1 -0
- package/utils/index.d.ts.map +1 -1
package/esm/index.mjs
CHANGED
|
@@ -10,6 +10,7 @@ var __decorateClass = (decorators, target, key, kind) => {
|
|
|
10
10
|
};
|
|
11
11
|
|
|
12
12
|
// plugins/plugin-codecall/src/codecall.plugin.ts
|
|
13
|
+
import CachePlugin from "@frontmcp/plugin-cache";
|
|
13
14
|
import {
|
|
14
15
|
DynamicPlugin,
|
|
15
16
|
FrontMcpLogger,
|
|
@@ -273,6 +274,104 @@ var DEFAULT_PLUGIN_OPTIONS = {
|
|
|
273
274
|
};
|
|
274
275
|
var codeCallPluginOptionsSchema = codeCallPluginOptionsObjectSchema.prefault(DEFAULT_PLUGIN_OPTIONS);
|
|
275
276
|
|
|
277
|
+
// plugins/plugin-codecall/src/providers/code-call.config.ts
|
|
278
|
+
import { Provider, ProviderScope, BaseConfig } from "@frontmcp/sdk";
|
|
279
|
+
var CodeCallConfig = class extends BaseConfig {
|
|
280
|
+
constructor(options = {}) {
|
|
281
|
+
const parsedConfig = codeCallPluginOptionsSchema.parse(options);
|
|
282
|
+
const resolvedVm = resolveVmOptions(parsedConfig.vm);
|
|
283
|
+
super({ ...parsedConfig, resolvedVm });
|
|
284
|
+
}
|
|
285
|
+
};
|
|
286
|
+
CodeCallConfig = __decorateClass([
|
|
287
|
+
Provider({
|
|
288
|
+
name: "codecall:config",
|
|
289
|
+
description: "CodeCall plugin configuration with validated defaults",
|
|
290
|
+
scope: ProviderScope.GLOBAL
|
|
291
|
+
})
|
|
292
|
+
], CodeCallConfig);
|
|
293
|
+
function resolveVmOptions(vmOptions) {
|
|
294
|
+
const preset = vmOptions?.preset ?? "secure";
|
|
295
|
+
const base = presetDefaults(preset);
|
|
296
|
+
return {
|
|
297
|
+
...base,
|
|
298
|
+
...vmOptions,
|
|
299
|
+
disabledBuiltins: vmOptions?.disabledBuiltins ?? base.disabledBuiltins,
|
|
300
|
+
disabledGlobals: vmOptions?.disabledGlobals ?? base.disabledGlobals
|
|
301
|
+
};
|
|
302
|
+
}
|
|
303
|
+
function presetDefaults(preset) {
|
|
304
|
+
switch (preset) {
|
|
305
|
+
case "locked_down":
|
|
306
|
+
return {
|
|
307
|
+
preset,
|
|
308
|
+
timeoutMs: 2e3,
|
|
309
|
+
allowLoops: false,
|
|
310
|
+
allowConsole: false,
|
|
311
|
+
maxSteps: 2e3,
|
|
312
|
+
disabledBuiltins: ["eval", "Function", "AsyncFunction"],
|
|
313
|
+
disabledGlobals: [
|
|
314
|
+
"require",
|
|
315
|
+
"process",
|
|
316
|
+
"fetch",
|
|
317
|
+
"setTimeout",
|
|
318
|
+
"setInterval",
|
|
319
|
+
"setImmediate",
|
|
320
|
+
"global",
|
|
321
|
+
"globalThis"
|
|
322
|
+
],
|
|
323
|
+
maxSanitizeDepth: 10,
|
|
324
|
+
maxSanitizeProperties: 1e3
|
|
325
|
+
};
|
|
326
|
+
case "balanced":
|
|
327
|
+
return {
|
|
328
|
+
preset,
|
|
329
|
+
timeoutMs: 5e3,
|
|
330
|
+
allowLoops: true,
|
|
331
|
+
allowConsole: true,
|
|
332
|
+
maxSteps: 1e4,
|
|
333
|
+
disabledBuiltins: ["eval", "Function", "AsyncFunction"],
|
|
334
|
+
disabledGlobals: ["require", "process", "fetch"],
|
|
335
|
+
maxSanitizeDepth: 50,
|
|
336
|
+
maxSanitizeProperties: 5e3
|
|
337
|
+
};
|
|
338
|
+
case "experimental":
|
|
339
|
+
return {
|
|
340
|
+
preset,
|
|
341
|
+
timeoutMs: 1e4,
|
|
342
|
+
allowLoops: true,
|
|
343
|
+
allowConsole: true,
|
|
344
|
+
maxSteps: 2e4,
|
|
345
|
+
disabledBuiltins: ["eval", "Function", "AsyncFunction"],
|
|
346
|
+
disabledGlobals: ["require", "process"],
|
|
347
|
+
maxSanitizeDepth: 100,
|
|
348
|
+
maxSanitizeProperties: 2e4
|
|
349
|
+
};
|
|
350
|
+
case "secure":
|
|
351
|
+
default:
|
|
352
|
+
return {
|
|
353
|
+
preset: "secure",
|
|
354
|
+
timeoutMs: 3500,
|
|
355
|
+
allowLoops: false,
|
|
356
|
+
allowConsole: true,
|
|
357
|
+
maxSteps: 5e3,
|
|
358
|
+
disabledBuiltins: ["eval", "Function", "AsyncFunction"],
|
|
359
|
+
disabledGlobals: [
|
|
360
|
+
"require",
|
|
361
|
+
"process",
|
|
362
|
+
"fetch",
|
|
363
|
+
"setTimeout",
|
|
364
|
+
"setInterval",
|
|
365
|
+
"setImmediate",
|
|
366
|
+
"global",
|
|
367
|
+
"globalThis"
|
|
368
|
+
],
|
|
369
|
+
maxSanitizeDepth: 50,
|
|
370
|
+
maxSanitizeProperties: 2e3
|
|
371
|
+
};
|
|
372
|
+
}
|
|
373
|
+
}
|
|
374
|
+
|
|
276
375
|
// plugins/plugin-codecall/src/services/tool-search.service.ts
|
|
277
376
|
import { TFIDFVectoria, VectoriaDB } from "vectoriadb";
|
|
278
377
|
|
|
@@ -1179,8 +1278,8 @@ var ToolSearchService = class _ToolSearchService {
|
|
|
1179
1278
|
};
|
|
1180
1279
|
|
|
1181
1280
|
// plugins/plugin-codecall/src/services/enclave.service.ts
|
|
1182
|
-
import { Provider, ProviderScope } from "@frontmcp/sdk";
|
|
1183
1281
|
import { Enclave } from "@enclave-vm/core";
|
|
1282
|
+
import { Provider as Provider2, ProviderScope as ProviderScope2 } from "@frontmcp/sdk";
|
|
1184
1283
|
var ScriptTooLargeError = class extends Error {
|
|
1185
1284
|
code = "SCRIPT_TOO_LARGE";
|
|
1186
1285
|
scriptLength;
|
|
@@ -1229,6 +1328,10 @@ var EnclaveService = class {
|
|
|
1229
1328
|
maxResolvedSize: this.sidecarOptions.maxResolvedSize,
|
|
1230
1329
|
allowComposites: this.sidecarOptions.allowComposites
|
|
1231
1330
|
} : void 0;
|
|
1331
|
+
const RESERVED_GLOBALS = /* @__PURE__ */ new Set(["getTool", "mcpLog", "mcpNotify"]);
|
|
1332
|
+
const safeNamespaces = Object.fromEntries(
|
|
1333
|
+
Object.entries(environment.namespaces ?? {}).filter(([key]) => !RESERVED_GLOBALS.has(key))
|
|
1334
|
+
);
|
|
1232
1335
|
const enclave = new Enclave({
|
|
1233
1336
|
timeout: this.vmOptions.timeoutMs,
|
|
1234
1337
|
maxToolCalls: this.vmOptions.maxSteps || 100,
|
|
@@ -1242,6 +1345,11 @@ var EnclaveService = class {
|
|
|
1242
1345
|
// Allow functions in globals since we intentionally provide getTool, mcpLog, mcpNotify, and console
|
|
1243
1346
|
allowFunctionsInGlobals: true,
|
|
1244
1347
|
globals: {
|
|
1348
|
+
// Tool namespaces (e.g. `acme.getUser`) flow through here. Spread
|
|
1349
|
+
// FIRST so the runtime reserved globals below are guaranteed
|
|
1350
|
+
// last-wins. Reserved keys have already been stripped above —
|
|
1351
|
+
// belt-and-braces ordering makes the invariant locally obvious.
|
|
1352
|
+
...safeNamespaces,
|
|
1245
1353
|
// Provide getTool as a custom global
|
|
1246
1354
|
getTool: environment.getTool,
|
|
1247
1355
|
// Provide logging functions if available
|
|
@@ -1338,10 +1446,10 @@ var EnclaveService = class {
|
|
|
1338
1446
|
}
|
|
1339
1447
|
};
|
|
1340
1448
|
EnclaveService = __decorateClass([
|
|
1341
|
-
|
|
1449
|
+
Provider2({
|
|
1342
1450
|
name: "codecall:enclave",
|
|
1343
1451
|
description: "Executes AgentScript code in a secure enclave",
|
|
1344
|
-
scope:
|
|
1452
|
+
scope: ProviderScope2.GLOBAL
|
|
1345
1453
|
})
|
|
1346
1454
|
], EnclaveService);
|
|
1347
1455
|
|
|
@@ -1485,10 +1593,295 @@ SearchTool = __decorateClass([
|
|
|
1485
1593
|
})
|
|
1486
1594
|
], SearchTool);
|
|
1487
1595
|
|
|
1488
|
-
// plugins/plugin-codecall/src/tools/
|
|
1489
|
-
import { toJSONSchema, z as z4, ZodType } from "@frontmcp/lazy-zod";
|
|
1596
|
+
// plugins/plugin-codecall/src/tools/search-skills.tool.ts
|
|
1490
1597
|
import { Tool as Tool2, ToolContext as ToolContext2 } from "@frontmcp/sdk";
|
|
1491
1598
|
|
|
1599
|
+
// plugins/plugin-codecall/src/tools/search-skills.schema.ts
|
|
1600
|
+
import { z as z3 } from "@frontmcp/lazy-zod";
|
|
1601
|
+
var searchSkillsToolDescription = `Search for EXECUTABLE skills. Each result returns the skill's description, tags, and the openapi operation IDs it can call from within AgentScript.
|
|
1602
|
+
|
|
1603
|
+
DECOMPOSE complex requests into atomic queries. AVOID re-searching: use excludeSkillNames.
|
|
1604
|
+
|
|
1605
|
+
INPUT:
|
|
1606
|
+
- queries: string[] (required) - atomic skill descriptions, max 10
|
|
1607
|
+
- tags?: string[] - filter to skills carrying any of these tags
|
|
1608
|
+
- excludeSkillNames?: string[] - skip already-discovered skills
|
|
1609
|
+
- topK?: number (default 5) - results per query
|
|
1610
|
+
- minRelevanceScore?: number (default 0.1) - minimum match threshold
|
|
1611
|
+
|
|
1612
|
+
OUTPUT: Flat deduplicated executable skill list. Each entry includes the operationIds the skill is allowed to call (via the markdown harvester). The agent can use those operationIds directly in execute() AgentScript via the generated namespaces (e.g. acme.getOrder({...})).
|
|
1613
|
+
|
|
1614
|
+
FLOW: searchSkills \u2192 describe \u2192 execute`;
|
|
1615
|
+
var searchSkillsToolInputSchema = {
|
|
1616
|
+
queries: z3.array(z3.string().min(2).max(256)).min(1).max(10).describe("Atomic skill queries. Split complex requests into simple actions."),
|
|
1617
|
+
tags: z3.array(z3.string().min(1).max(64)).max(16).optional().describe("Filter to skills with any of these tags"),
|
|
1618
|
+
excludeSkillNames: z3.array(z3.string()).max(50).optional().describe("Skip already-known skill names"),
|
|
1619
|
+
topK: z3.number().int().positive().max(50).optional().default(5).describe("Results per query (default 5)"),
|
|
1620
|
+
minRelevanceScore: z3.number().min(0).max(1).optional().default(0.1).describe("Minimum relevance threshold (default 0.1)")
|
|
1621
|
+
};
|
|
1622
|
+
var referencedOperationSchema = z3.object({
|
|
1623
|
+
spec: z3.string().describe('OpenAPI spec id (e.g. "acme")'),
|
|
1624
|
+
operationId: z3.string().describe('OpenAPI operation id (e.g. "getOrder")')
|
|
1625
|
+
});
|
|
1626
|
+
var skillSearchHitSchema = z3.object({
|
|
1627
|
+
name: z3.string().describe("Skill name"),
|
|
1628
|
+
description: z3.string().describe("Short description of what the skill does"),
|
|
1629
|
+
tags: z3.array(z3.string()).describe("Tags carried by the skill"),
|
|
1630
|
+
/**
|
|
1631
|
+
* OpenAPI operations the skill is allowed to call. Inlined so the agent
|
|
1632
|
+
* can author AgentScript from a single search response.
|
|
1633
|
+
*/
|
|
1634
|
+
operations: z3.array(referencedOperationSchema).describe("OpenAPI operations the skill can call"),
|
|
1635
|
+
/** Decorator-declared tools (for skills built the legacy way). */
|
|
1636
|
+
tools: z3.array(z3.string()).describe("Tool names the skill declares (if any)"),
|
|
1637
|
+
relevanceScore: z3.number().min(0).max(1).describe("Match score (0-1)"),
|
|
1638
|
+
matchedQueries: z3.array(z3.string()).describe("Which queries matched this skill"),
|
|
1639
|
+
source: z3.enum(["local", "external"]).describe("Where the skill was loaded from")
|
|
1640
|
+
});
|
|
1641
|
+
var searchSkillsToolOutputSchema = z3.object({
|
|
1642
|
+
skills: z3.array(skillSearchHitSchema).describe("Deduplicated executable skills, sorted by relevance"),
|
|
1643
|
+
warnings: z3.array(
|
|
1644
|
+
z3.object({
|
|
1645
|
+
type: z3.enum(["no_results", "low_relevance", "excluded_skill_not_found"]).describe("Warning type"),
|
|
1646
|
+
message: z3.string().describe("Warning message"),
|
|
1647
|
+
affectedSkills: z3.array(z3.string()).optional().describe("Affected skill names")
|
|
1648
|
+
})
|
|
1649
|
+
).describe("Search warnings"),
|
|
1650
|
+
totalExecutableSkills: z3.number().int().nonnegative().describe("Total executable skills available")
|
|
1651
|
+
});
|
|
1652
|
+
|
|
1653
|
+
// plugins/plugin-codecall/src/tools/search-skills.tool.ts
|
|
1654
|
+
var SearchSkillsTool = class extends ToolContext2 {
|
|
1655
|
+
async execute(input) {
|
|
1656
|
+
const { queries, tags, excludeSkillNames = [], topK = 5, minRelevanceScore = 0.1 } = input;
|
|
1657
|
+
const skillRegistry = this.scope.skills;
|
|
1658
|
+
const executableSkills = skillRegistry.getExecutableSkills();
|
|
1659
|
+
const executableSet = new Set(executableSkills.map((s) => s.name));
|
|
1660
|
+
const totalExecutableSkills = executableSkills.length;
|
|
1661
|
+
const warnings = [];
|
|
1662
|
+
const nonExistentExcluded = excludeSkillNames.filter((n) => !executableSet.has(n));
|
|
1663
|
+
if (nonExistentExcluded.length > 0) {
|
|
1664
|
+
warnings.push({
|
|
1665
|
+
type: "excluded_skill_not_found",
|
|
1666
|
+
message: `Excluded skills not found: ${nonExistentExcluded.join(", ")}`,
|
|
1667
|
+
affectedSkills: nonExistentExcluded
|
|
1668
|
+
});
|
|
1669
|
+
}
|
|
1670
|
+
const matches = /* @__PURE__ */ new Map();
|
|
1671
|
+
let lowRelevanceCount = 0;
|
|
1672
|
+
const excludedSet = new Set(excludeSkillNames);
|
|
1673
|
+
const perQueryResults = await Promise.all(
|
|
1674
|
+
queries.map(
|
|
1675
|
+
(query) => skillRegistry.search(query, { topK, tags, minScore: minRelevanceScore }).then((results) => ({ query, results }))
|
|
1676
|
+
)
|
|
1677
|
+
);
|
|
1678
|
+
for (const { query, results } of perQueryResults) {
|
|
1679
|
+
for (const result of results) {
|
|
1680
|
+
const name = result.metadata.name;
|
|
1681
|
+
if (!executableSet.has(name)) continue;
|
|
1682
|
+
if (excludedSet.has(name)) continue;
|
|
1683
|
+
if (result.score < minRelevanceScore) {
|
|
1684
|
+
lowRelevanceCount++;
|
|
1685
|
+
continue;
|
|
1686
|
+
}
|
|
1687
|
+
const existing = matches.get(name);
|
|
1688
|
+
if (existing) {
|
|
1689
|
+
existing.matchedQueries.push(query);
|
|
1690
|
+
existing.relevanceScore = Math.max(existing.relevanceScore, result.score);
|
|
1691
|
+
} else {
|
|
1692
|
+
const ops = result.metadata.referencedOperations ?? [];
|
|
1693
|
+
const toolNames = (result.metadata.tools ?? []).map((t) => {
|
|
1694
|
+
if (typeof t === "string") return t;
|
|
1695
|
+
if (typeof t === "object" && t !== null && "name" in t) return t.name;
|
|
1696
|
+
return null;
|
|
1697
|
+
}).filter((n) => typeof n === "string");
|
|
1698
|
+
matches.set(name, {
|
|
1699
|
+
name,
|
|
1700
|
+
description: result.metadata.description,
|
|
1701
|
+
tags: result.metadata.tags ?? [],
|
|
1702
|
+
operations: ops.map((op) => ({ spec: op.spec, operationId: op.operationId })),
|
|
1703
|
+
tools: toolNames,
|
|
1704
|
+
relevanceScore: result.score,
|
|
1705
|
+
matchedQueries: [query],
|
|
1706
|
+
source: result.source
|
|
1707
|
+
});
|
|
1708
|
+
}
|
|
1709
|
+
}
|
|
1710
|
+
}
|
|
1711
|
+
const skills = Array.from(matches.values()).sort((a, b) => b.relevanceScore - a.relevanceScore);
|
|
1712
|
+
if (skills.length === 0) {
|
|
1713
|
+
warnings.push({
|
|
1714
|
+
type: "no_results",
|
|
1715
|
+
message: `No executable skills found for queries: ${queries.join(", ")}${tags?.length ? ` with tags: ${tags.join(", ")}` : ""}`
|
|
1716
|
+
});
|
|
1717
|
+
}
|
|
1718
|
+
if (lowRelevanceCount > 0 && skills.length > 0) {
|
|
1719
|
+
warnings.push({
|
|
1720
|
+
type: "low_relevance",
|
|
1721
|
+
message: `${lowRelevanceCount} result(s) filtered due to relevance below ${minRelevanceScore}`
|
|
1722
|
+
});
|
|
1723
|
+
}
|
|
1724
|
+
return { skills, warnings, totalExecutableSkills };
|
|
1725
|
+
}
|
|
1726
|
+
};
|
|
1727
|
+
SearchSkillsTool = __decorateClass([
|
|
1728
|
+
Tool2({
|
|
1729
|
+
name: "codecall:searchSkills",
|
|
1730
|
+
cache: {
|
|
1731
|
+
ttl: 60,
|
|
1732
|
+
slideWindow: false
|
|
1733
|
+
},
|
|
1734
|
+
codecall: {
|
|
1735
|
+
enabledInCodeCall: false,
|
|
1736
|
+
visibleInListTools: true
|
|
1737
|
+
},
|
|
1738
|
+
description: searchSkillsToolDescription,
|
|
1739
|
+
inputSchema: searchSkillsToolInputSchema,
|
|
1740
|
+
outputSchema: searchSkillsToolOutputSchema,
|
|
1741
|
+
annotations: {
|
|
1742
|
+
readOnlyHint: true,
|
|
1743
|
+
openWorldHint: true
|
|
1744
|
+
}
|
|
1745
|
+
})
|
|
1746
|
+
], SearchSkillsTool);
|
|
1747
|
+
|
|
1748
|
+
// plugins/plugin-codecall/src/tools/search-knowledge.tool.ts
|
|
1749
|
+
import { Tool as Tool3, ToolContext as ToolContext3 } from "@frontmcp/sdk";
|
|
1750
|
+
|
|
1751
|
+
// plugins/plugin-codecall/src/tools/search-knowledge.schema.ts
|
|
1752
|
+
import { z as z4 } from "@frontmcp/lazy-zod";
|
|
1753
|
+
var searchKnowledgeToolDescription = `Search for KNOWLEDGE-ONLY skills \u2014 domain context the agent should read before deciding what to do. These skills have no tools and no openapi operation refs; they are pure prose / references / examples.
|
|
1754
|
+
|
|
1755
|
+
USE WHEN: the agent needs background to interpret a request, validate eligibility, or recall a procedure that isn't yet executable.
|
|
1756
|
+
|
|
1757
|
+
INPUT:
|
|
1758
|
+
- queries: string[] (required) - atomic context queries, max 10
|
|
1759
|
+
- tags?: string[] - filter to knowledge carrying any of these tags
|
|
1760
|
+
- excludeSkillNames?: string[] - skip already-loaded knowledge
|
|
1761
|
+
- topK?: number (default 5) - results per query
|
|
1762
|
+
- minRelevanceScore?: number (default 0.1) - minimum match threshold
|
|
1763
|
+
|
|
1764
|
+
OUTPUT: Deduplicated knowledge skill list with description + tags. To read the body, follow up with describe(skillName) or the skill:// resource URI.
|
|
1765
|
+
|
|
1766
|
+
FLOW: searchKnowledge \u2192 describe (for body) \u2192 continue with searchSkills`;
|
|
1767
|
+
var searchKnowledgeToolInputSchema = {
|
|
1768
|
+
queries: z4.array(z4.string().min(2).max(256)).min(1).max(10).describe("Atomic context queries."),
|
|
1769
|
+
tags: z4.array(z4.string().min(1).max(64)).max(16).optional().describe("Filter to skills with any of these tags"),
|
|
1770
|
+
excludeSkillNames: z4.array(z4.string()).max(50).optional().describe("Skip already-loaded knowledge skill names"),
|
|
1771
|
+
topK: z4.number().int().positive().max(50).optional().default(5).describe("Results per query (default 5)"),
|
|
1772
|
+
minRelevanceScore: z4.number().min(0).max(1).optional().default(0.1).describe("Minimum relevance threshold (default 0.1)")
|
|
1773
|
+
};
|
|
1774
|
+
var knowledgeHitSchema = z4.object({
|
|
1775
|
+
name: z4.string().describe("Skill name"),
|
|
1776
|
+
description: z4.string().describe("Short description of what the knowledge covers"),
|
|
1777
|
+
tags: z4.array(z4.string()).describe("Tags carried by the skill"),
|
|
1778
|
+
relevanceScore: z4.number().min(0).max(1).describe("Match score (0-1)"),
|
|
1779
|
+
matchedQueries: z4.array(z4.string()).describe("Which queries matched this knowledge"),
|
|
1780
|
+
source: z4.enum(["local", "external"]).describe("Where the skill was loaded from")
|
|
1781
|
+
});
|
|
1782
|
+
var searchKnowledgeToolOutputSchema = z4.object({
|
|
1783
|
+
knowledge: z4.array(knowledgeHitSchema).describe("Deduplicated knowledge skills, sorted by relevance"),
|
|
1784
|
+
warnings: z4.array(
|
|
1785
|
+
z4.object({
|
|
1786
|
+
type: z4.enum(["no_results", "low_relevance", "excluded_skill_not_found"]).describe("Warning type"),
|
|
1787
|
+
message: z4.string().describe("Warning message"),
|
|
1788
|
+
affectedSkills: z4.array(z4.string()).optional().describe("Affected skill names")
|
|
1789
|
+
})
|
|
1790
|
+
).describe("Search warnings"),
|
|
1791
|
+
totalKnowledgeSkills: z4.number().int().nonnegative().describe("Total knowledge-only skills available")
|
|
1792
|
+
});
|
|
1793
|
+
|
|
1794
|
+
// plugins/plugin-codecall/src/tools/search-knowledge.tool.ts
|
|
1795
|
+
var SearchKnowledgeTool = class extends ToolContext3 {
|
|
1796
|
+
async execute(input) {
|
|
1797
|
+
const { queries, tags, excludeSkillNames = [], topK = 5, minRelevanceScore = 0.1 } = input;
|
|
1798
|
+
const skillRegistry = this.scope.skills;
|
|
1799
|
+
const knowledgeSkills = skillRegistry.getKnowledgeOnlySkills();
|
|
1800
|
+
const knowledgeSet = new Set(knowledgeSkills.map((s) => s.name));
|
|
1801
|
+
const totalKnowledgeSkills = knowledgeSkills.length;
|
|
1802
|
+
const warnings = [];
|
|
1803
|
+
const nonExistentExcluded = excludeSkillNames.filter((n) => !knowledgeSet.has(n));
|
|
1804
|
+
if (nonExistentExcluded.length > 0) {
|
|
1805
|
+
warnings.push({
|
|
1806
|
+
type: "excluded_skill_not_found",
|
|
1807
|
+
message: `Excluded knowledge skills not found: ${nonExistentExcluded.join(", ")}`,
|
|
1808
|
+
affectedSkills: nonExistentExcluded
|
|
1809
|
+
});
|
|
1810
|
+
}
|
|
1811
|
+
const matches = /* @__PURE__ */ new Map();
|
|
1812
|
+
let lowRelevanceCount = 0;
|
|
1813
|
+
const excludedSet = new Set(excludeSkillNames);
|
|
1814
|
+
const perQueryResults = await Promise.all(
|
|
1815
|
+
queries.map(
|
|
1816
|
+
(query) => skillRegistry.search(query, { topK, tags, minScore: minRelevanceScore }).then((results) => ({ query, results }))
|
|
1817
|
+
)
|
|
1818
|
+
);
|
|
1819
|
+
for (const { query, results } of perQueryResults) {
|
|
1820
|
+
for (const result of results) {
|
|
1821
|
+
const name = result.metadata.name;
|
|
1822
|
+
if (!knowledgeSet.has(name)) continue;
|
|
1823
|
+
if (excludedSet.has(name)) continue;
|
|
1824
|
+
if (result.score < minRelevanceScore) {
|
|
1825
|
+
lowRelevanceCount++;
|
|
1826
|
+
continue;
|
|
1827
|
+
}
|
|
1828
|
+
const existing = matches.get(name);
|
|
1829
|
+
if (existing) {
|
|
1830
|
+
existing.matchedQueries.push(query);
|
|
1831
|
+
existing.relevanceScore = Math.max(existing.relevanceScore, result.score);
|
|
1832
|
+
} else {
|
|
1833
|
+
matches.set(name, {
|
|
1834
|
+
name,
|
|
1835
|
+
description: result.metadata.description,
|
|
1836
|
+
tags: result.metadata.tags ?? [],
|
|
1837
|
+
relevanceScore: result.score,
|
|
1838
|
+
matchedQueries: [query],
|
|
1839
|
+
source: result.source
|
|
1840
|
+
});
|
|
1841
|
+
}
|
|
1842
|
+
}
|
|
1843
|
+
}
|
|
1844
|
+
const knowledge = Array.from(matches.values()).sort((a, b) => b.relevanceScore - a.relevanceScore);
|
|
1845
|
+
if (knowledge.length === 0) {
|
|
1846
|
+
warnings.push({
|
|
1847
|
+
type: "no_results",
|
|
1848
|
+
message: `No knowledge skills found for queries: ${queries.join(", ")}${tags?.length ? ` with tags: ${tags.join(", ")}` : ""}`
|
|
1849
|
+
});
|
|
1850
|
+
}
|
|
1851
|
+
if (lowRelevanceCount > 0 && knowledge.length > 0) {
|
|
1852
|
+
warnings.push({
|
|
1853
|
+
type: "low_relevance",
|
|
1854
|
+
message: `${lowRelevanceCount} result(s) filtered due to relevance below ${minRelevanceScore}`
|
|
1855
|
+
});
|
|
1856
|
+
}
|
|
1857
|
+
return { knowledge, warnings, totalKnowledgeSkills };
|
|
1858
|
+
}
|
|
1859
|
+
};
|
|
1860
|
+
SearchKnowledgeTool = __decorateClass([
|
|
1861
|
+
Tool3({
|
|
1862
|
+
name: "codecall:searchKnowledge",
|
|
1863
|
+
cache: {
|
|
1864
|
+
ttl: 60,
|
|
1865
|
+
slideWindow: false
|
|
1866
|
+
},
|
|
1867
|
+
codecall: {
|
|
1868
|
+
enabledInCodeCall: false,
|
|
1869
|
+
visibleInListTools: true
|
|
1870
|
+
},
|
|
1871
|
+
description: searchKnowledgeToolDescription,
|
|
1872
|
+
inputSchema: searchKnowledgeToolInputSchema,
|
|
1873
|
+
outputSchema: searchKnowledgeToolOutputSchema,
|
|
1874
|
+
annotations: {
|
|
1875
|
+
readOnlyHint: true,
|
|
1876
|
+
openWorldHint: true
|
|
1877
|
+
}
|
|
1878
|
+
})
|
|
1879
|
+
], SearchKnowledgeTool);
|
|
1880
|
+
|
|
1881
|
+
// plugins/plugin-codecall/src/tools/describe.tool.ts
|
|
1882
|
+
import { toJSONSchema, z as z6, ZodType } from "@frontmcp/lazy-zod";
|
|
1883
|
+
import { Tool as Tool4, ToolContext as ToolContext4 } from "@frontmcp/sdk";
|
|
1884
|
+
|
|
1492
1885
|
// plugins/plugin-codecall/src/errors/tool-call.errors.ts
|
|
1493
1886
|
var TOOL_CALL_ERROR_CODES = {
|
|
1494
1887
|
NOT_FOUND: "NOT_FOUND",
|
|
@@ -1567,6 +1960,70 @@ function assertNotSelfReference(toolName) {
|
|
|
1567
1960
|
}
|
|
1568
1961
|
}
|
|
1569
1962
|
|
|
1963
|
+
// plugins/plugin-codecall/src/utils/build-tool-namespaces.ts
|
|
1964
|
+
var IDENT_RE = /^[A-Za-z_$][A-Za-z0-9_$]*$/;
|
|
1965
|
+
var RESERVED_NAMESPACES = /* @__PURE__ */ new Set([
|
|
1966
|
+
"console",
|
|
1967
|
+
"Math",
|
|
1968
|
+
"JSON",
|
|
1969
|
+
"Object",
|
|
1970
|
+
"Array",
|
|
1971
|
+
"String",
|
|
1972
|
+
"Number",
|
|
1973
|
+
"Boolean",
|
|
1974
|
+
"Promise",
|
|
1975
|
+
"Symbol",
|
|
1976
|
+
"Map",
|
|
1977
|
+
"Set",
|
|
1978
|
+
"WeakMap",
|
|
1979
|
+
"WeakSet",
|
|
1980
|
+
"Date",
|
|
1981
|
+
"Error",
|
|
1982
|
+
"RegExp",
|
|
1983
|
+
"globalThis",
|
|
1984
|
+
"global",
|
|
1985
|
+
"window",
|
|
1986
|
+
"self",
|
|
1987
|
+
"undefined",
|
|
1988
|
+
"null",
|
|
1989
|
+
"true",
|
|
1990
|
+
"false",
|
|
1991
|
+
"callTool",
|
|
1992
|
+
"getTool",
|
|
1993
|
+
"mcpLog",
|
|
1994
|
+
"mcpNotify"
|
|
1995
|
+
]);
|
|
1996
|
+
function buildToolNamespaces(tools, callTool) {
|
|
1997
|
+
const namespaces = {};
|
|
1998
|
+
const skipped = [];
|
|
1999
|
+
for (const tool of tools) {
|
|
2000
|
+
const name = tool?.name;
|
|
2001
|
+
if (typeof name !== "string" || name.length === 0) continue;
|
|
2002
|
+
const dot = name.indexOf(".");
|
|
2003
|
+
if (dot <= 0 || dot === name.length - 1) {
|
|
2004
|
+
skipped.push({ name, reason: "no-namespace-prefix" });
|
|
2005
|
+
continue;
|
|
2006
|
+
}
|
|
2007
|
+
const ns = name.slice(0, dot);
|
|
2008
|
+
const method = name.slice(dot + 1);
|
|
2009
|
+
if (!IDENT_RE.test(ns) || !IDENT_RE.test(method)) {
|
|
2010
|
+
skipped.push({ name, reason: "invalid-identifier" });
|
|
2011
|
+
continue;
|
|
2012
|
+
}
|
|
2013
|
+
if (RESERVED_NAMESPACES.has(ns)) {
|
|
2014
|
+
skipped.push({ name, reason: "reserved-namespace" });
|
|
2015
|
+
continue;
|
|
2016
|
+
}
|
|
2017
|
+
const bucket = namespaces[ns] ?? (namespaces[ns] = {});
|
|
2018
|
+
if (Object.prototype.hasOwnProperty.call(bucket, method)) {
|
|
2019
|
+
skipped.push({ name, reason: "duplicate-method" });
|
|
2020
|
+
continue;
|
|
2021
|
+
}
|
|
2022
|
+
bucket[method] = (input, options) => callTool(name, input, options);
|
|
2023
|
+
}
|
|
2024
|
+
return { namespaces, skipped };
|
|
2025
|
+
}
|
|
2026
|
+
|
|
1570
2027
|
// plugins/plugin-codecall/src/utils/describe.utils.ts
|
|
1571
2028
|
var INTENT_PATTERNS = {
|
|
1572
2029
|
create: /^(create|add|new|insert|make|append|register|generate|produce|build|construct|provision|instantiate|define|compose|draft)/i,
|
|
@@ -1856,7 +2313,7 @@ function extractResultFromCallToolResult(mcpResult) {
|
|
|
1856
2313
|
}
|
|
1857
2314
|
|
|
1858
2315
|
// plugins/plugin-codecall/src/tools/describe.schema.ts
|
|
1859
|
-
import { z as
|
|
2316
|
+
import { z as z5 } from "@frontmcp/lazy-zod";
|
|
1860
2317
|
import { ToolAnnotationsSchema } from "@frontmcp/protocol";
|
|
1861
2318
|
var describeToolDescription = `Get input/output schemas for tools from search results.
|
|
1862
2319
|
|
|
@@ -1866,7 +2323,7 @@ OUTPUT per tool: inputSchema (JSON Schema), outputSchema (JSON Schema), usageExa
|
|
|
1866
2323
|
IMPORTANT: If notFound array is non-empty \u2192 re-search with corrected queries.
|
|
1867
2324
|
FLOW: search \u2192 describe \u2192 execute/invoke`;
|
|
1868
2325
|
var describeToolInputSchema = {
|
|
1869
|
-
toolNames:
|
|
2326
|
+
toolNames: z5.array(z5.string()).min(1).superRefine((toolNames, ctx) => {
|
|
1870
2327
|
const seen = /* @__PURE__ */ new Set();
|
|
1871
2328
|
const duplicates = /* @__PURE__ */ new Set();
|
|
1872
2329
|
for (const name of toolNames) {
|
|
@@ -1877,7 +2334,7 @@ var describeToolInputSchema = {
|
|
|
1877
2334
|
}
|
|
1878
2335
|
if (duplicates.size > 0) {
|
|
1879
2336
|
ctx.addIssue({
|
|
1880
|
-
code:
|
|
2337
|
+
code: z5.ZodIssueCode.custom,
|
|
1881
2338
|
message: `Duplicate tool names are not allowed: ${Array.from(duplicates).join(", ")}`
|
|
1882
2339
|
});
|
|
1883
2340
|
}
|
|
@@ -1885,30 +2342,30 @@ var describeToolInputSchema = {
|
|
|
1885
2342
|
'Array of unique tool names (from codecall:search results) to fetch their detailed schemas and usage examples. Example: ["users:list", "billing:getInvoice"]'
|
|
1886
2343
|
)
|
|
1887
2344
|
};
|
|
1888
|
-
var describeToolOutputSchema =
|
|
1889
|
-
tools:
|
|
1890
|
-
|
|
1891
|
-
name:
|
|
1892
|
-
appId:
|
|
1893
|
-
description:
|
|
1894
|
-
inputSchema:
|
|
1895
|
-
outputSchema:
|
|
2345
|
+
var describeToolOutputSchema = z5.object({
|
|
2346
|
+
tools: z5.array(
|
|
2347
|
+
z5.object({
|
|
2348
|
+
name: z5.string().describe("Tool name to be used in callTool() within codecall:execute scripts"),
|
|
2349
|
+
appId: z5.string().describe("The app ID this tool belongs to"),
|
|
2350
|
+
description: z5.string().describe("Detailed description of what this tool does"),
|
|
2351
|
+
inputSchema: z5.record(z5.string(), z5.unknown()).nullable().describe("JSON Schema object describing the tool input parameters"),
|
|
2352
|
+
outputSchema: z5.record(z5.string(), z5.unknown()).nullable().describe("JSON Schema object describing the tool output structure"),
|
|
1896
2353
|
annotations: ToolAnnotationsSchema.optional().describe("MCP tool annotations (metadata)"),
|
|
1897
|
-
usageExamples:
|
|
1898
|
-
|
|
1899
|
-
description:
|
|
1900
|
-
code:
|
|
2354
|
+
usageExamples: z5.array(
|
|
2355
|
+
z5.object({
|
|
2356
|
+
description: z5.string().describe("Description of what this example demonstrates"),
|
|
2357
|
+
code: z5.string().describe(
|
|
1901
2358
|
'JavaScript code example showing how to call this tool using callTool(). Format: const result = await callTool("tool:name", { ...params });'
|
|
1902
2359
|
)
|
|
1903
2360
|
})
|
|
1904
2361
|
).max(5).describe("Up to 5 practical examples of how to use this tool in a codecall:execute script")
|
|
1905
2362
|
})
|
|
1906
2363
|
).describe("Array of tool descriptions with schemas and usage examples"),
|
|
1907
|
-
notFound:
|
|
2364
|
+
notFound: z5.array(z5.string()).optional().describe("Tool names that were requested but not found in the index. Check these for typos.")
|
|
1908
2365
|
});
|
|
1909
2366
|
|
|
1910
2367
|
// plugins/plugin-codecall/src/tools/describe.tool.ts
|
|
1911
|
-
var DescribeTool = class extends
|
|
2368
|
+
var DescribeTool = class extends ToolContext4 {
|
|
1912
2369
|
async execute(input) {
|
|
1913
2370
|
const { toolNames } = input;
|
|
1914
2371
|
const tools = [];
|
|
@@ -1928,7 +2385,7 @@ var DescribeTool = class extends ToolContext2 {
|
|
|
1928
2385
|
}
|
|
1929
2386
|
const appId = this.extractAppId(tool);
|
|
1930
2387
|
const inputSchema = this.getInputSchema(tool);
|
|
1931
|
-
const outputSchema = this.toJsonSchema(tool.outputSchema);
|
|
2388
|
+
const outputSchema = this.toJsonSchema(tool.rawOutputSchema ?? tool.outputSchema);
|
|
1932
2389
|
const usageExamples = this.generateExamples(tool, inputSchema ?? void 0);
|
|
1933
2390
|
tools.push({
|
|
1934
2391
|
name: tool.name,
|
|
@@ -1959,7 +2416,7 @@ var DescribeTool = class extends ToolContext2 {
|
|
|
1959
2416
|
try {
|
|
1960
2417
|
const firstValue = Object.values(tool.inputSchema)[0];
|
|
1961
2418
|
if (firstValue instanceof ZodType) {
|
|
1962
|
-
return toJSONSchema(
|
|
2419
|
+
return toJSONSchema(z6.object(tool.inputSchema));
|
|
1963
2420
|
}
|
|
1964
2421
|
} catch {
|
|
1965
2422
|
}
|
|
@@ -1991,7 +2448,7 @@ var DescribeTool = class extends ToolContext2 {
|
|
|
1991
2448
|
const firstValue = Object.values(obj)[0];
|
|
1992
2449
|
if (firstValue instanceof ZodType) {
|
|
1993
2450
|
try {
|
|
1994
|
-
return toJSONSchema(
|
|
2451
|
+
return toJSONSchema(z6.object(obj));
|
|
1995
2452
|
} catch {
|
|
1996
2453
|
return null;
|
|
1997
2454
|
}
|
|
@@ -2054,7 +2511,7 @@ return result;`
|
|
|
2054
2511
|
}
|
|
2055
2512
|
};
|
|
2056
2513
|
DescribeTool = __decorateClass([
|
|
2057
|
-
|
|
2514
|
+
Tool4({
|
|
2058
2515
|
name: "codecall:describe",
|
|
2059
2516
|
cache: {
|
|
2060
2517
|
ttl: 60,
|
|
@@ -2076,10 +2533,10 @@ DescribeTool = __decorateClass([
|
|
|
2076
2533
|
], DescribeTool);
|
|
2077
2534
|
|
|
2078
2535
|
// plugins/plugin-codecall/src/tools/execute.tool.ts
|
|
2079
|
-
import { Tool as
|
|
2536
|
+
import { Tool as Tool5, ToolContext as ToolContext5 } from "@frontmcp/sdk";
|
|
2080
2537
|
|
|
2081
2538
|
// plugins/plugin-codecall/src/tools/execute.schema.ts
|
|
2082
|
-
import { z as
|
|
2539
|
+
import { z as z7 } from "@frontmcp/lazy-zod";
|
|
2083
2540
|
var MIN_EXECUTE_SCRIPT_LENGTH = 'return callTool("a",{})'.length;
|
|
2084
2541
|
var executeToolDescription = `Execute AgentScript (safe JS subset) for multi-tool orchestration.
|
|
2085
2542
|
|
|
@@ -2103,72 +2560,72 @@ ERRORS: NOT_FOUND | VALIDATION | EXECUTION | TIMEOUT | ACCESS_DENIED
|
|
|
2103
2560
|
STATUS: ok | syntax_error | illegal_access | runtime_error | tool_error | timeout
|
|
2104
2561
|
LIMITS: 10K iter/loop, 30s timeout, 100 calls max`;
|
|
2105
2562
|
var executeToolInputSchema = {
|
|
2106
|
-
script:
|
|
2563
|
+
script: z7.string().min(MIN_EXECUTE_SCRIPT_LENGTH).max(100 * 1024).describe(
|
|
2107
2564
|
"JavaScript code to execute in the sandbox. Must return a value (implicitly or via explicit return). Use callTool(name, input) to invoke tools."
|
|
2108
2565
|
),
|
|
2109
|
-
allowedTools:
|
|
2566
|
+
allowedTools: z7.array(z7.string()).optional().describe(
|
|
2110
2567
|
'Optional whitelist of tool names that can be called from this script. If not provided, all indexed tools are available. Example: ["users:list", "billing:getInvoice"]'
|
|
2111
2568
|
)
|
|
2112
2569
|
};
|
|
2113
|
-
var syntaxErrorPayloadSchema =
|
|
2114
|
-
message:
|
|
2115
|
-
location:
|
|
2116
|
-
line:
|
|
2117
|
-
column:
|
|
2570
|
+
var syntaxErrorPayloadSchema = z7.object({
|
|
2571
|
+
message: z7.string(),
|
|
2572
|
+
location: z7.object({
|
|
2573
|
+
line: z7.number(),
|
|
2574
|
+
column: z7.number()
|
|
2118
2575
|
}).optional()
|
|
2119
2576
|
});
|
|
2120
|
-
var illegalAccessErrorPayloadSchema =
|
|
2121
|
-
message:
|
|
2122
|
-
kind:
|
|
2123
|
-
|
|
2124
|
-
|
|
2125
|
-
|
|
2577
|
+
var illegalAccessErrorPayloadSchema = z7.object({
|
|
2578
|
+
message: z7.string(),
|
|
2579
|
+
kind: z7.union([
|
|
2580
|
+
z7.literal("IllegalBuiltinAccess"),
|
|
2581
|
+
z7.literal("DisallowedGlobal"),
|
|
2582
|
+
z7.string()
|
|
2126
2583
|
// same as your original type: 'A' | 'B' | string
|
|
2127
2584
|
])
|
|
2128
2585
|
});
|
|
2129
|
-
var runtimeErrorPayloadSchema =
|
|
2130
|
-
source:
|
|
2131
|
-
message:
|
|
2132
|
-
name:
|
|
2133
|
-
stack:
|
|
2586
|
+
var runtimeErrorPayloadSchema = z7.object({
|
|
2587
|
+
source: z7.literal("script"),
|
|
2588
|
+
message: z7.string(),
|
|
2589
|
+
name: z7.string().optional(),
|
|
2590
|
+
stack: z7.string().optional()
|
|
2134
2591
|
});
|
|
2135
|
-
var toolErrorPayloadSchema =
|
|
2136
|
-
source:
|
|
2137
|
-
toolName:
|
|
2138
|
-
toolInput:
|
|
2139
|
-
message:
|
|
2140
|
-
code:
|
|
2141
|
-
details:
|
|
2592
|
+
var toolErrorPayloadSchema = z7.object({
|
|
2593
|
+
source: z7.literal("tool"),
|
|
2594
|
+
toolName: z7.string(),
|
|
2595
|
+
toolInput: z7.unknown(),
|
|
2596
|
+
message: z7.string(),
|
|
2597
|
+
code: z7.string().optional(),
|
|
2598
|
+
details: z7.unknown().optional()
|
|
2142
2599
|
});
|
|
2143
|
-
var timeoutErrorPayloadSchema =
|
|
2144
|
-
message:
|
|
2600
|
+
var timeoutErrorPayloadSchema = z7.object({
|
|
2601
|
+
message: z7.string()
|
|
2145
2602
|
});
|
|
2146
|
-
var codeCallOkResultSchema =
|
|
2147
|
-
status:
|
|
2148
|
-
result:
|
|
2149
|
-
logs:
|
|
2603
|
+
var codeCallOkResultSchema = z7.object({
|
|
2604
|
+
status: z7.literal("ok"),
|
|
2605
|
+
result: z7.unknown(),
|
|
2606
|
+
logs: z7.array(z7.string()).optional()
|
|
2150
2607
|
});
|
|
2151
|
-
var codeCallSyntaxErrorResultSchema =
|
|
2152
|
-
status:
|
|
2608
|
+
var codeCallSyntaxErrorResultSchema = z7.object({
|
|
2609
|
+
status: z7.literal("syntax_error"),
|
|
2153
2610
|
error: syntaxErrorPayloadSchema
|
|
2154
2611
|
});
|
|
2155
|
-
var codeCallIllegalAccessResultSchema =
|
|
2156
|
-
status:
|
|
2612
|
+
var codeCallIllegalAccessResultSchema = z7.object({
|
|
2613
|
+
status: z7.literal("illegal_access"),
|
|
2157
2614
|
error: illegalAccessErrorPayloadSchema
|
|
2158
2615
|
});
|
|
2159
|
-
var codeCallRuntimeErrorResultSchema =
|
|
2160
|
-
status:
|
|
2616
|
+
var codeCallRuntimeErrorResultSchema = z7.object({
|
|
2617
|
+
status: z7.literal("runtime_error"),
|
|
2161
2618
|
error: runtimeErrorPayloadSchema
|
|
2162
2619
|
});
|
|
2163
|
-
var codeCallToolErrorResultSchema =
|
|
2164
|
-
status:
|
|
2620
|
+
var codeCallToolErrorResultSchema = z7.object({
|
|
2621
|
+
status: z7.literal("tool_error"),
|
|
2165
2622
|
error: toolErrorPayloadSchema
|
|
2166
2623
|
});
|
|
2167
|
-
var codeCallTimeoutResultSchema =
|
|
2168
|
-
status:
|
|
2624
|
+
var codeCallTimeoutResultSchema = z7.object({
|
|
2625
|
+
status: z7.literal("timeout"),
|
|
2169
2626
|
error: timeoutErrorPayloadSchema
|
|
2170
2627
|
});
|
|
2171
|
-
var executeToolOutputSchema =
|
|
2628
|
+
var executeToolOutputSchema = z7.discriminatedUnion("status", [
|
|
2172
2629
|
codeCallOkResultSchema,
|
|
2173
2630
|
codeCallSyntaxErrorResultSchema,
|
|
2174
2631
|
codeCallIllegalAccessResultSchema,
|
|
@@ -2177,104 +2634,6 @@ var executeToolOutputSchema = z5.discriminatedUnion("status", [
|
|
|
2177
2634
|
codeCallTimeoutResultSchema
|
|
2178
2635
|
]);
|
|
2179
2636
|
|
|
2180
|
-
// plugins/plugin-codecall/src/providers/code-call.config.ts
|
|
2181
|
-
import { Provider as Provider2, ProviderScope as ProviderScope2, BaseConfig } from "@frontmcp/sdk";
|
|
2182
|
-
var CodeCallConfig = class extends BaseConfig {
|
|
2183
|
-
constructor(options = {}) {
|
|
2184
|
-
const parsedConfig = codeCallPluginOptionsSchema.parse(options);
|
|
2185
|
-
const resolvedVm = resolveVmOptions(parsedConfig.vm);
|
|
2186
|
-
super({ ...parsedConfig, resolvedVm });
|
|
2187
|
-
}
|
|
2188
|
-
};
|
|
2189
|
-
CodeCallConfig = __decorateClass([
|
|
2190
|
-
Provider2({
|
|
2191
|
-
name: "codecall:config",
|
|
2192
|
-
description: "CodeCall plugin configuration with validated defaults",
|
|
2193
|
-
scope: ProviderScope2.GLOBAL
|
|
2194
|
-
})
|
|
2195
|
-
], CodeCallConfig);
|
|
2196
|
-
function resolveVmOptions(vmOptions) {
|
|
2197
|
-
const preset = vmOptions?.preset ?? "secure";
|
|
2198
|
-
const base = presetDefaults(preset);
|
|
2199
|
-
return {
|
|
2200
|
-
...base,
|
|
2201
|
-
...vmOptions,
|
|
2202
|
-
disabledBuiltins: vmOptions?.disabledBuiltins ?? base.disabledBuiltins,
|
|
2203
|
-
disabledGlobals: vmOptions?.disabledGlobals ?? base.disabledGlobals
|
|
2204
|
-
};
|
|
2205
|
-
}
|
|
2206
|
-
function presetDefaults(preset) {
|
|
2207
|
-
switch (preset) {
|
|
2208
|
-
case "locked_down":
|
|
2209
|
-
return {
|
|
2210
|
-
preset,
|
|
2211
|
-
timeoutMs: 2e3,
|
|
2212
|
-
allowLoops: false,
|
|
2213
|
-
allowConsole: false,
|
|
2214
|
-
maxSteps: 2e3,
|
|
2215
|
-
disabledBuiltins: ["eval", "Function", "AsyncFunction"],
|
|
2216
|
-
disabledGlobals: [
|
|
2217
|
-
"require",
|
|
2218
|
-
"process",
|
|
2219
|
-
"fetch",
|
|
2220
|
-
"setTimeout",
|
|
2221
|
-
"setInterval",
|
|
2222
|
-
"setImmediate",
|
|
2223
|
-
"global",
|
|
2224
|
-
"globalThis"
|
|
2225
|
-
],
|
|
2226
|
-
maxSanitizeDepth: 10,
|
|
2227
|
-
maxSanitizeProperties: 1e3
|
|
2228
|
-
};
|
|
2229
|
-
case "balanced":
|
|
2230
|
-
return {
|
|
2231
|
-
preset,
|
|
2232
|
-
timeoutMs: 5e3,
|
|
2233
|
-
allowLoops: true,
|
|
2234
|
-
allowConsole: true,
|
|
2235
|
-
maxSteps: 1e4,
|
|
2236
|
-
disabledBuiltins: ["eval", "Function", "AsyncFunction"],
|
|
2237
|
-
disabledGlobals: ["require", "process", "fetch"],
|
|
2238
|
-
maxSanitizeDepth: 50,
|
|
2239
|
-
maxSanitizeProperties: 5e3
|
|
2240
|
-
};
|
|
2241
|
-
case "experimental":
|
|
2242
|
-
return {
|
|
2243
|
-
preset,
|
|
2244
|
-
timeoutMs: 1e4,
|
|
2245
|
-
allowLoops: true,
|
|
2246
|
-
allowConsole: true,
|
|
2247
|
-
maxSteps: 2e4,
|
|
2248
|
-
disabledBuiltins: ["eval", "Function", "AsyncFunction"],
|
|
2249
|
-
disabledGlobals: ["require", "process"],
|
|
2250
|
-
maxSanitizeDepth: 100,
|
|
2251
|
-
maxSanitizeProperties: 2e4
|
|
2252
|
-
};
|
|
2253
|
-
case "secure":
|
|
2254
|
-
default:
|
|
2255
|
-
return {
|
|
2256
|
-
preset: "secure",
|
|
2257
|
-
timeoutMs: 3500,
|
|
2258
|
-
allowLoops: false,
|
|
2259
|
-
allowConsole: true,
|
|
2260
|
-
maxSteps: 5e3,
|
|
2261
|
-
disabledBuiltins: ["eval", "Function", "AsyncFunction"],
|
|
2262
|
-
disabledGlobals: [
|
|
2263
|
-
"require",
|
|
2264
|
-
"process",
|
|
2265
|
-
"fetch",
|
|
2266
|
-
"setTimeout",
|
|
2267
|
-
"setInterval",
|
|
2268
|
-
"setImmediate",
|
|
2269
|
-
"global",
|
|
2270
|
-
"globalThis"
|
|
2271
|
-
],
|
|
2272
|
-
maxSanitizeDepth: 50,
|
|
2273
|
-
maxSanitizeProperties: 2e3
|
|
2274
|
-
};
|
|
2275
|
-
}
|
|
2276
|
-
}
|
|
2277
|
-
|
|
2278
2637
|
// plugins/plugin-codecall/src/tools/execute.tool.ts
|
|
2279
2638
|
function getErrorCode(error) {
|
|
2280
2639
|
if (!(error instanceof Error)) {
|
|
@@ -2291,7 +2650,7 @@ function getErrorCode(error) {
|
|
|
2291
2650
|
}
|
|
2292
2651
|
return TOOL_CALL_ERROR_CODES.EXECUTION;
|
|
2293
2652
|
}
|
|
2294
|
-
var ExecuteTool = class extends
|
|
2653
|
+
var ExecuteTool = class extends ToolContext5 {
|
|
2295
2654
|
async execute(input) {
|
|
2296
2655
|
const { script, allowedTools } = input;
|
|
2297
2656
|
const allowedToolSet = allowedTools ? new Set(allowedTools) : null;
|
|
@@ -2363,6 +2722,22 @@ var ExecuteTool = class extends ToolContext3 {
|
|
|
2363
2722
|
this.logger?.debug("Notification sent", { event, payload });
|
|
2364
2723
|
}
|
|
2365
2724
|
};
|
|
2725
|
+
try {
|
|
2726
|
+
const registeredTools = this.scope.tools.getTools(true);
|
|
2727
|
+
const { namespaces, skipped } = buildToolNamespaces(registeredTools, environment.callTool);
|
|
2728
|
+
environment.namespaces = namespaces;
|
|
2729
|
+
if (skipped.length > 0) {
|
|
2730
|
+
this.logger?.debug?.("codecall: tools skipped during namespace generation", {
|
|
2731
|
+
count: skipped.length,
|
|
2732
|
+
// Cap the debug payload so a huge skip list doesn't bloat logs.
|
|
2733
|
+
sample: skipped.slice(0, 25)
|
|
2734
|
+
});
|
|
2735
|
+
}
|
|
2736
|
+
} catch (error) {
|
|
2737
|
+
this.logger?.warn?.("codecall: failed to build tool namespaces", {
|
|
2738
|
+
error: error instanceof Error ? error.message : String(error)
|
|
2739
|
+
});
|
|
2740
|
+
}
|
|
2366
2741
|
const enclaveService = this.get(EnclaveService);
|
|
2367
2742
|
const config = this.get(CodeCallConfig);
|
|
2368
2743
|
try {
|
|
@@ -2441,7 +2816,7 @@ var ExecuteTool = class extends ToolContext3 {
|
|
|
2441
2816
|
}
|
|
2442
2817
|
};
|
|
2443
2818
|
ExecuteTool = __decorateClass([
|
|
2444
|
-
|
|
2819
|
+
Tool5({
|
|
2445
2820
|
name: "codecall:execute",
|
|
2446
2821
|
cache: {
|
|
2447
2822
|
ttl: 0,
|
|
@@ -2459,10 +2834,10 @@ ExecuteTool = __decorateClass([
|
|
|
2459
2834
|
], ExecuteTool);
|
|
2460
2835
|
|
|
2461
2836
|
// plugins/plugin-codecall/src/tools/invoke.tool.ts
|
|
2462
|
-
import { Tool as
|
|
2837
|
+
import { Tool as Tool6, ToolContext as ToolContext6 } from "@frontmcp/sdk";
|
|
2463
2838
|
|
|
2464
2839
|
// plugins/plugin-codecall/src/tools/invoke.schema.ts
|
|
2465
|
-
import { z as
|
|
2840
|
+
import { z as z8 } from "@frontmcp/lazy-zod";
|
|
2466
2841
|
import { CallToolResultSchema } from "@frontmcp/protocol";
|
|
2467
2842
|
var invokeToolDescription = `Call ONE tool directly. Returns standard MCP CallToolResult.
|
|
2468
2843
|
|
|
@@ -2475,10 +2850,10 @@ ERRORS: tool_not_found (\u2192 re-search) | validation_error | execution_error |
|
|
|
2475
2850
|
|
|
2476
2851
|
FLOW: search \u2192 describe \u2192 invoke`;
|
|
2477
2852
|
var invokeToolInputSchema = {
|
|
2478
|
-
tool:
|
|
2853
|
+
tool: z8.string().describe(
|
|
2479
2854
|
'The name of the tool to invoke (e.g., "users:getById", "billing:getInvoice"). Must be a tool you discovered via codecall:search.'
|
|
2480
2855
|
),
|
|
2481
|
-
input:
|
|
2856
|
+
input: z8.record(z8.string(), z8.unknown()).describe(
|
|
2482
2857
|
"The input parameters for the tool. Structure must match the tool's input schema (check codecall:describe for schema details)."
|
|
2483
2858
|
)
|
|
2484
2859
|
};
|
|
@@ -2491,7 +2866,7 @@ function buildErrorResult(message) {
|
|
|
2491
2866
|
isError: true
|
|
2492
2867
|
};
|
|
2493
2868
|
}
|
|
2494
|
-
var InvokeTool = class extends
|
|
2869
|
+
var InvokeTool = class extends ToolContext6 {
|
|
2495
2870
|
async execute(input) {
|
|
2496
2871
|
const { tool: toolName, input: toolInput } = input;
|
|
2497
2872
|
if (isBlockedSelfReference(toolName)) {
|
|
@@ -2517,7 +2892,7 @@ var InvokeTool = class extends ToolContext4 {
|
|
|
2517
2892
|
}
|
|
2518
2893
|
};
|
|
2519
2894
|
InvokeTool = __decorateClass([
|
|
2520
|
-
|
|
2895
|
+
Tool6({
|
|
2521
2896
|
name: "codecall:invoke",
|
|
2522
2897
|
cache: {
|
|
2523
2898
|
ttl: 0,
|
|
@@ -2535,7 +2910,6 @@ InvokeTool = __decorateClass([
|
|
|
2535
2910
|
], InvokeTool);
|
|
2536
2911
|
|
|
2537
2912
|
// plugins/plugin-codecall/src/codecall.plugin.ts
|
|
2538
|
-
import CachePlugin from "@frontmcp/plugin-cache";
|
|
2539
2913
|
var CodeCallPlugin = class extends DynamicPlugin {
|
|
2540
2914
|
options;
|
|
2541
2915
|
cachedLogger;
|
|
@@ -2612,7 +2986,6 @@ var CodeCallPlugin = class extends DynamicPlugin {
|
|
|
2612
2986
|
* @param mode - The current CodeCall mode
|
|
2613
2987
|
* @returns true if tool should be visible
|
|
2614
2988
|
*/
|
|
2615
|
-
// eslint-disable-next-line @typescript-eslint/no-explicit-any -- ToolEntry generics vary across call sites
|
|
2616
2989
|
shouldShowInListTools(tool, mode) {
|
|
2617
2990
|
if (this.isCodeCallTool(tool)) {
|
|
2618
2991
|
return true;
|
|
@@ -2644,15 +3017,13 @@ var CodeCallPlugin = class extends DynamicPlugin {
|
|
|
2644
3017
|
* Check if a tool is a CodeCall meta-tool.
|
|
2645
3018
|
* CodeCall meta-tools always remain visible.
|
|
2646
3019
|
*/
|
|
2647
|
-
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
2648
3020
|
isCodeCallTool(tool) {
|
|
2649
3021
|
const name = tool.name || tool.fullName;
|
|
2650
|
-
return name.startsWith("codecall:");
|
|
3022
|
+
return typeof name === "string" && name.startsWith("codecall:");
|
|
2651
3023
|
}
|
|
2652
3024
|
/**
|
|
2653
3025
|
* Extract CodeCall-specific metadata from a tool.
|
|
2654
3026
|
*/
|
|
2655
|
-
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
2656
3027
|
getCodeCallMetadata(tool) {
|
|
2657
3028
|
return tool.metadata?.["codecall"];
|
|
2658
3029
|
}
|
|
@@ -2666,7 +3037,7 @@ CodeCallPlugin = __decorateClass([
|
|
|
2666
3037
|
description: "CodeCall plugin: AgentScript-based meta-tools for orchestrating MCP tools",
|
|
2667
3038
|
providers: [],
|
|
2668
3039
|
plugins: [CachePlugin],
|
|
2669
|
-
tools: [SearchTool, DescribeTool, ExecuteTool, InvokeTool]
|
|
3040
|
+
tools: [SearchTool, SearchSkillsTool, SearchKnowledgeTool, DescribeTool, ExecuteTool, InvokeTool]
|
|
2670
3041
|
})
|
|
2671
3042
|
], CodeCallPlugin);
|
|
2672
3043
|
export {
|