@dexto/tools-builtins 1.6.17 → 1.6.19
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/implementations/invoke-skill-tool.cjs +64 -3
- package/dist/implementations/invoke-skill-tool.d.ts.map +1 -1
- package/dist/implementations/invoke-skill-tool.js +64 -3
- package/dist/implementations/invoke-skill-tool.test.cjs +122 -0
- package/dist/implementations/invoke-skill-tool.test.d.ts +2 -0
- package/dist/implementations/invoke-skill-tool.test.d.ts.map +1 -0
- package/dist/implementations/invoke-skill-tool.test.js +121 -0
- package/package.json +4 -4
|
@@ -94,6 +94,17 @@ function createInvokeSkillTool() {
|
|
|
94
94
|
}
|
|
95
95
|
}
|
|
96
96
|
const promptDef = await promptManager.getPromptDefinition(skillKey);
|
|
97
|
+
const taskForker = context.services?.taskForker;
|
|
98
|
+
if (promptDef?.context === "fork" && !taskForker) {
|
|
99
|
+
return {
|
|
100
|
+
error: `Skill '${skill}' requires fork execution (context: fork), but agent spawning is not available.`,
|
|
101
|
+
skill: skillKey
|
|
102
|
+
};
|
|
103
|
+
}
|
|
104
|
+
const skillMcpError = await ensureSkillMcpServersConnected(skill, matchedInfo, context);
|
|
105
|
+
if (skillMcpError) {
|
|
106
|
+
return skillMcpError;
|
|
107
|
+
}
|
|
97
108
|
if (promptDef?.context !== "fork" && promptDef?.allowedTools && promptDef.allowedTools.length > 0 && context.sessionId && context.agent?.toolManager) {
|
|
98
109
|
try {
|
|
99
110
|
context.agent.toolManager.addSessionAutoApproveTools(
|
|
@@ -111,8 +122,8 @@ function createInvokeSkillTool() {
|
|
|
111
122
|
const flattened = (0, import_core.flattenPromptResult)(promptResult);
|
|
112
123
|
const content = flattened.text;
|
|
113
124
|
if (promptDef?.context === "fork") {
|
|
114
|
-
const
|
|
115
|
-
if (!
|
|
125
|
+
const activeTaskForker = taskForker;
|
|
126
|
+
if (!activeTaskForker) {
|
|
116
127
|
return {
|
|
117
128
|
error: `Skill '${skill}' requires fork execution (context: fork), but agent spawning is not available.`,
|
|
118
129
|
skill: skillKey
|
|
@@ -137,7 +148,7 @@ ${content}` : content;
|
|
|
137
148
|
if (context.sessionId) {
|
|
138
149
|
forkOptions.sessionId = context.sessionId;
|
|
139
150
|
}
|
|
140
|
-
const result = await
|
|
151
|
+
const result = await activeTaskForker.fork(forkOptions);
|
|
141
152
|
if (result.success) {
|
|
142
153
|
return result.response ?? "Task completed successfully.";
|
|
143
154
|
}
|
|
@@ -167,11 +178,61 @@ Parameters:
|
|
|
167
178
|
Execution modes:
|
|
168
179
|
- **Inline skills**: Return instructions for you to follow in the current conversation
|
|
169
180
|
- **Fork skills**: Automatically execute in an isolated subagent and return the result (no additional tool calls needed)
|
|
181
|
+
- **Bundled MCP skills**: Automatically connect any MCP servers carried inside the skill bundle when the skill is invoked
|
|
170
182
|
|
|
171
183
|
Fork skills run in complete isolation without access to conversation history. They're useful for tasks that should run independently.
|
|
172
184
|
|
|
173
185
|
Available skills are listed in your system prompt. Use the skill name exactly as shown.`;
|
|
174
186
|
}
|
|
187
|
+
function getSkillBundledMcpServers(promptInfo) {
|
|
188
|
+
const rawServers = promptInfo?.metadata?.mcpServers;
|
|
189
|
+
if (!rawServers || typeof rawServers !== "object" || Array.isArray(rawServers)) {
|
|
190
|
+
return {};
|
|
191
|
+
}
|
|
192
|
+
return Object.fromEntries(
|
|
193
|
+
Object.entries(rawServers).filter(
|
|
194
|
+
([, config]) => typeof config === "object" && config !== null && !Array.isArray(config)
|
|
195
|
+
)
|
|
196
|
+
);
|
|
197
|
+
}
|
|
198
|
+
async function ensureSkillMcpServersConnected(skill, promptInfo, context) {
|
|
199
|
+
const mcpServers = getSkillBundledMcpServers(promptInfo);
|
|
200
|
+
const serverNames = Object.keys(mcpServers);
|
|
201
|
+
if (serverNames.length === 0) {
|
|
202
|
+
return void 0;
|
|
203
|
+
}
|
|
204
|
+
if (!context.agent?.addMcpServer || !context.agent.getMcpServerStatus || !context.agent.enableMcpServer) {
|
|
205
|
+
return {
|
|
206
|
+
error: `Skill '${skill}' requires bundled MCP servers (${serverNames.join(", ")}), but this agent does not support dynamic MCP loading.`,
|
|
207
|
+
mcpServers: serverNames
|
|
208
|
+
};
|
|
209
|
+
}
|
|
210
|
+
try {
|
|
211
|
+
for (const [serverName, serverConfig] of Object.entries(mcpServers)) {
|
|
212
|
+
let serverStatus = context.agent.getMcpServerStatus(serverName);
|
|
213
|
+
if (!serverStatus) {
|
|
214
|
+
await context.agent.addMcpServer(serverName, serverConfig);
|
|
215
|
+
serverStatus = context.agent.getMcpServerStatus(serverName);
|
|
216
|
+
}
|
|
217
|
+
if (!serverStatus?.enabled || serverStatus.status !== "connected") {
|
|
218
|
+
await context.agent.enableMcpServer(serverName);
|
|
219
|
+
serverStatus = context.agent.getMcpServerStatus(serverName);
|
|
220
|
+
}
|
|
221
|
+
if (!serverStatus || serverStatus.status !== "connected") {
|
|
222
|
+
return {
|
|
223
|
+
error: `Skill '${skill}' requires MCP server '${serverName}', but it is currently ${serverStatus?.status ?? "unavailable"}${serverStatus?.error ? `: ${serverStatus.error}` : ""}.`,
|
|
224
|
+
mcpServers: serverNames
|
|
225
|
+
};
|
|
226
|
+
}
|
|
227
|
+
}
|
|
228
|
+
} catch (error) {
|
|
229
|
+
return {
|
|
230
|
+
error: error instanceof Error ? error.message : "Failed to connect bundled MCP servers for skill",
|
|
231
|
+
mcpServers: serverNames
|
|
232
|
+
};
|
|
233
|
+
}
|
|
234
|
+
return void 0;
|
|
235
|
+
}
|
|
175
236
|
// Annotate the CommonJS export names for ESM import in node:
|
|
176
237
|
0 && (module.exports = {
|
|
177
238
|
createInvokeSkillTool
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"invoke-skill-tool.d.ts","sourceRoot":"","sources":["../../src/implementations/invoke-skill-tool.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAExB,OAAO,KAAK,
|
|
1
|
+
{"version":3,"file":"invoke-skill-tool.d.ts","sourceRoot":"","sources":["../../src/implementations/invoke-skill-tool.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAExB,OAAO,KAAK,EAIR,IAAI,EAEP,MAAM,aAAa,CAAC;AAErB,QAAA,MAAM,sBAAsB;;;;;;;;;;;;EAgBf,CAAC;AAEd;;;;;;GAMG;AACH,wBAAgB,qBAAqB,IAAI,IAAI,CAAC,OAAO,sBAAsB,CAAC,CAuK3E"}
|
|
@@ -71,6 +71,17 @@ function createInvokeSkillTool() {
|
|
|
71
71
|
}
|
|
72
72
|
}
|
|
73
73
|
const promptDef = await promptManager.getPromptDefinition(skillKey);
|
|
74
|
+
const taskForker = context.services?.taskForker;
|
|
75
|
+
if (promptDef?.context === "fork" && !taskForker) {
|
|
76
|
+
return {
|
|
77
|
+
error: `Skill '${skill}' requires fork execution (context: fork), but agent spawning is not available.`,
|
|
78
|
+
skill: skillKey
|
|
79
|
+
};
|
|
80
|
+
}
|
|
81
|
+
const skillMcpError = await ensureSkillMcpServersConnected(skill, matchedInfo, context);
|
|
82
|
+
if (skillMcpError) {
|
|
83
|
+
return skillMcpError;
|
|
84
|
+
}
|
|
74
85
|
if (promptDef?.context !== "fork" && promptDef?.allowedTools && promptDef.allowedTools.length > 0 && context.sessionId && context.agent?.toolManager) {
|
|
75
86
|
try {
|
|
76
87
|
context.agent.toolManager.addSessionAutoApproveTools(
|
|
@@ -88,8 +99,8 @@ function createInvokeSkillTool() {
|
|
|
88
99
|
const flattened = flattenPromptResult(promptResult);
|
|
89
100
|
const content = flattened.text;
|
|
90
101
|
if (promptDef?.context === "fork") {
|
|
91
|
-
const
|
|
92
|
-
if (!
|
|
102
|
+
const activeTaskForker = taskForker;
|
|
103
|
+
if (!activeTaskForker) {
|
|
93
104
|
return {
|
|
94
105
|
error: `Skill '${skill}' requires fork execution (context: fork), but agent spawning is not available.`,
|
|
95
106
|
skill: skillKey
|
|
@@ -114,7 +125,7 @@ ${content}` : content;
|
|
|
114
125
|
if (context.sessionId) {
|
|
115
126
|
forkOptions.sessionId = context.sessionId;
|
|
116
127
|
}
|
|
117
|
-
const result = await
|
|
128
|
+
const result = await activeTaskForker.fork(forkOptions);
|
|
118
129
|
if (result.success) {
|
|
119
130
|
return result.response ?? "Task completed successfully.";
|
|
120
131
|
}
|
|
@@ -144,11 +155,61 @@ Parameters:
|
|
|
144
155
|
Execution modes:
|
|
145
156
|
- **Inline skills**: Return instructions for you to follow in the current conversation
|
|
146
157
|
- **Fork skills**: Automatically execute in an isolated subagent and return the result (no additional tool calls needed)
|
|
158
|
+
- **Bundled MCP skills**: Automatically connect any MCP servers carried inside the skill bundle when the skill is invoked
|
|
147
159
|
|
|
148
160
|
Fork skills run in complete isolation without access to conversation history. They're useful for tasks that should run independently.
|
|
149
161
|
|
|
150
162
|
Available skills are listed in your system prompt. Use the skill name exactly as shown.`;
|
|
151
163
|
}
|
|
164
|
+
function getSkillBundledMcpServers(promptInfo) {
|
|
165
|
+
const rawServers = promptInfo?.metadata?.mcpServers;
|
|
166
|
+
if (!rawServers || typeof rawServers !== "object" || Array.isArray(rawServers)) {
|
|
167
|
+
return {};
|
|
168
|
+
}
|
|
169
|
+
return Object.fromEntries(
|
|
170
|
+
Object.entries(rawServers).filter(
|
|
171
|
+
([, config]) => typeof config === "object" && config !== null && !Array.isArray(config)
|
|
172
|
+
)
|
|
173
|
+
);
|
|
174
|
+
}
|
|
175
|
+
async function ensureSkillMcpServersConnected(skill, promptInfo, context) {
|
|
176
|
+
const mcpServers = getSkillBundledMcpServers(promptInfo);
|
|
177
|
+
const serverNames = Object.keys(mcpServers);
|
|
178
|
+
if (serverNames.length === 0) {
|
|
179
|
+
return void 0;
|
|
180
|
+
}
|
|
181
|
+
if (!context.agent?.addMcpServer || !context.agent.getMcpServerStatus || !context.agent.enableMcpServer) {
|
|
182
|
+
return {
|
|
183
|
+
error: `Skill '${skill}' requires bundled MCP servers (${serverNames.join(", ")}), but this agent does not support dynamic MCP loading.`,
|
|
184
|
+
mcpServers: serverNames
|
|
185
|
+
};
|
|
186
|
+
}
|
|
187
|
+
try {
|
|
188
|
+
for (const [serverName, serverConfig] of Object.entries(mcpServers)) {
|
|
189
|
+
let serverStatus = context.agent.getMcpServerStatus(serverName);
|
|
190
|
+
if (!serverStatus) {
|
|
191
|
+
await context.agent.addMcpServer(serverName, serverConfig);
|
|
192
|
+
serverStatus = context.agent.getMcpServerStatus(serverName);
|
|
193
|
+
}
|
|
194
|
+
if (!serverStatus?.enabled || serverStatus.status !== "connected") {
|
|
195
|
+
await context.agent.enableMcpServer(serverName);
|
|
196
|
+
serverStatus = context.agent.getMcpServerStatus(serverName);
|
|
197
|
+
}
|
|
198
|
+
if (!serverStatus || serverStatus.status !== "connected") {
|
|
199
|
+
return {
|
|
200
|
+
error: `Skill '${skill}' requires MCP server '${serverName}', but it is currently ${serverStatus?.status ?? "unavailable"}${serverStatus?.error ? `: ${serverStatus.error}` : ""}.`,
|
|
201
|
+
mcpServers: serverNames
|
|
202
|
+
};
|
|
203
|
+
}
|
|
204
|
+
}
|
|
205
|
+
} catch (error) {
|
|
206
|
+
return {
|
|
207
|
+
error: error instanceof Error ? error.message : "Failed to connect bundled MCP servers for skill",
|
|
208
|
+
mcpServers: serverNames
|
|
209
|
+
};
|
|
210
|
+
}
|
|
211
|
+
return void 0;
|
|
212
|
+
}
|
|
152
213
|
export {
|
|
153
214
|
createInvokeSkillTool
|
|
154
215
|
};
|
|
@@ -0,0 +1,122 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var import_vitest = require("vitest");
|
|
3
|
+
var import_invoke_skill_tool = require("./invoke-skill-tool.js");
|
|
4
|
+
function createPromptInfo() {
|
|
5
|
+
return {
|
|
6
|
+
name: "echo-custom-mcp",
|
|
7
|
+
displayName: "echo-custom-mcp",
|
|
8
|
+
commandName: "echo-custom-mcp",
|
|
9
|
+
source: "config",
|
|
10
|
+
metadata: {
|
|
11
|
+
type: "file",
|
|
12
|
+
filePath: "/tmp/skills/echo-custom-mcp/SKILL.md",
|
|
13
|
+
mcpServers: {
|
|
14
|
+
skill_echo_demo: {
|
|
15
|
+
type: "stdio",
|
|
16
|
+
command: "node",
|
|
17
|
+
args: ["scripts/echo-mcp-server.mjs"]
|
|
18
|
+
}
|
|
19
|
+
}
|
|
20
|
+
}
|
|
21
|
+
};
|
|
22
|
+
}
|
|
23
|
+
(0, import_vitest.describe)("invoke_skill tool", () => {
|
|
24
|
+
(0, import_vitest.it)("retries previously registered bundled MCP servers before returning an error", async () => {
|
|
25
|
+
const promptInfo = createPromptInfo();
|
|
26
|
+
const promptManager = {
|
|
27
|
+
listAutoInvocablePrompts: import_vitest.vi.fn().mockResolvedValue({ "config:echo-custom-mcp": promptInfo }),
|
|
28
|
+
getPromptDefinition: import_vitest.vi.fn().mockResolvedValue(void 0),
|
|
29
|
+
getPrompt: import_vitest.vi.fn().mockResolvedValue({
|
|
30
|
+
messages: [
|
|
31
|
+
{
|
|
32
|
+
content: {
|
|
33
|
+
type: "text",
|
|
34
|
+
text: "Use the bundled echo MCP tool."
|
|
35
|
+
}
|
|
36
|
+
}
|
|
37
|
+
]
|
|
38
|
+
})
|
|
39
|
+
};
|
|
40
|
+
const addMcpServer = import_vitest.vi.fn();
|
|
41
|
+
const enableMcpServer = import_vitest.vi.fn().mockResolvedValue(void 0);
|
|
42
|
+
const getMcpServerStatus = import_vitest.vi.fn().mockReturnValueOnce({
|
|
43
|
+
name: "skill_echo_demo",
|
|
44
|
+
type: "stdio",
|
|
45
|
+
enabled: true,
|
|
46
|
+
status: "error",
|
|
47
|
+
error: "Request timed out"
|
|
48
|
+
}).mockReturnValueOnce({
|
|
49
|
+
name: "skill_echo_demo",
|
|
50
|
+
type: "stdio",
|
|
51
|
+
enabled: true,
|
|
52
|
+
status: "connected"
|
|
53
|
+
});
|
|
54
|
+
const tool = (0, import_invoke_skill_tool.createInvokeSkillTool)();
|
|
55
|
+
const result = await tool.execute(
|
|
56
|
+
{
|
|
57
|
+
skill: "echo-custom-mcp"
|
|
58
|
+
},
|
|
59
|
+
{
|
|
60
|
+
logger: {
|
|
61
|
+
warn: import_vitest.vi.fn()
|
|
62
|
+
},
|
|
63
|
+
services: {
|
|
64
|
+
prompts: promptManager
|
|
65
|
+
},
|
|
66
|
+
agent: {
|
|
67
|
+
addMcpServer,
|
|
68
|
+
getMcpServerStatus,
|
|
69
|
+
enableMcpServer
|
|
70
|
+
}
|
|
71
|
+
}
|
|
72
|
+
);
|
|
73
|
+
(0, import_vitest.expect)(addMcpServer).not.toHaveBeenCalled();
|
|
74
|
+
(0, import_vitest.expect)(enableMcpServer).toHaveBeenCalledWith("skill_echo_demo");
|
|
75
|
+
(0, import_vitest.expect)(getMcpServerStatus).toHaveBeenCalledTimes(2);
|
|
76
|
+
(0, import_vitest.expect)(result).toMatchObject({
|
|
77
|
+
skill: "config:echo-custom-mcp",
|
|
78
|
+
content: "Use the bundled echo MCP tool."
|
|
79
|
+
});
|
|
80
|
+
});
|
|
81
|
+
(0, import_vitest.it)("does not connect bundled MCP servers when fork execution is unavailable", async () => {
|
|
82
|
+
const promptInfo = createPromptInfo();
|
|
83
|
+
const promptManager = {
|
|
84
|
+
listAutoInvocablePrompts: import_vitest.vi.fn().mockResolvedValue({ "config:echo-custom-mcp": promptInfo }),
|
|
85
|
+
getPromptDefinition: import_vitest.vi.fn().mockResolvedValue({
|
|
86
|
+
name: "echo-custom-mcp",
|
|
87
|
+
context: "fork"
|
|
88
|
+
}),
|
|
89
|
+
getPrompt: import_vitest.vi.fn()
|
|
90
|
+
};
|
|
91
|
+
const addMcpServer = import_vitest.vi.fn();
|
|
92
|
+
const enableMcpServer = import_vitest.vi.fn();
|
|
93
|
+
const getMcpServerStatus = import_vitest.vi.fn();
|
|
94
|
+
const tool = (0, import_invoke_skill_tool.createInvokeSkillTool)();
|
|
95
|
+
const result = await tool.execute(
|
|
96
|
+
{
|
|
97
|
+
skill: "echo-custom-mcp"
|
|
98
|
+
},
|
|
99
|
+
{
|
|
100
|
+
logger: {
|
|
101
|
+
warn: import_vitest.vi.fn()
|
|
102
|
+
},
|
|
103
|
+
services: {
|
|
104
|
+
prompts: promptManager
|
|
105
|
+
},
|
|
106
|
+
agent: {
|
|
107
|
+
addMcpServer,
|
|
108
|
+
getMcpServerStatus,
|
|
109
|
+
enableMcpServer
|
|
110
|
+
}
|
|
111
|
+
}
|
|
112
|
+
);
|
|
113
|
+
(0, import_vitest.expect)(addMcpServer).not.toHaveBeenCalled();
|
|
114
|
+
(0, import_vitest.expect)(enableMcpServer).not.toHaveBeenCalled();
|
|
115
|
+
(0, import_vitest.expect)(getMcpServerStatus).not.toHaveBeenCalled();
|
|
116
|
+
(0, import_vitest.expect)(promptManager.getPrompt).not.toHaveBeenCalled();
|
|
117
|
+
(0, import_vitest.expect)(result).toEqual({
|
|
118
|
+
error: "Skill 'echo-custom-mcp' requires fork execution (context: fork), but agent spawning is not available.",
|
|
119
|
+
skill: "config:echo-custom-mcp"
|
|
120
|
+
});
|
|
121
|
+
});
|
|
122
|
+
});
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"invoke-skill-tool.test.d.ts","sourceRoot":"","sources":["../../src/implementations/invoke-skill-tool.test.ts"],"names":[],"mappings":""}
|
|
@@ -0,0 +1,121 @@
|
|
|
1
|
+
import { describe, expect, it, vi } from "vitest";
|
|
2
|
+
import { createInvokeSkillTool } from "./invoke-skill-tool.js";
|
|
3
|
+
function createPromptInfo() {
|
|
4
|
+
return {
|
|
5
|
+
name: "echo-custom-mcp",
|
|
6
|
+
displayName: "echo-custom-mcp",
|
|
7
|
+
commandName: "echo-custom-mcp",
|
|
8
|
+
source: "config",
|
|
9
|
+
metadata: {
|
|
10
|
+
type: "file",
|
|
11
|
+
filePath: "/tmp/skills/echo-custom-mcp/SKILL.md",
|
|
12
|
+
mcpServers: {
|
|
13
|
+
skill_echo_demo: {
|
|
14
|
+
type: "stdio",
|
|
15
|
+
command: "node",
|
|
16
|
+
args: ["scripts/echo-mcp-server.mjs"]
|
|
17
|
+
}
|
|
18
|
+
}
|
|
19
|
+
}
|
|
20
|
+
};
|
|
21
|
+
}
|
|
22
|
+
describe("invoke_skill tool", () => {
|
|
23
|
+
it("retries previously registered bundled MCP servers before returning an error", async () => {
|
|
24
|
+
const promptInfo = createPromptInfo();
|
|
25
|
+
const promptManager = {
|
|
26
|
+
listAutoInvocablePrompts: vi.fn().mockResolvedValue({ "config:echo-custom-mcp": promptInfo }),
|
|
27
|
+
getPromptDefinition: vi.fn().mockResolvedValue(void 0),
|
|
28
|
+
getPrompt: vi.fn().mockResolvedValue({
|
|
29
|
+
messages: [
|
|
30
|
+
{
|
|
31
|
+
content: {
|
|
32
|
+
type: "text",
|
|
33
|
+
text: "Use the bundled echo MCP tool."
|
|
34
|
+
}
|
|
35
|
+
}
|
|
36
|
+
]
|
|
37
|
+
})
|
|
38
|
+
};
|
|
39
|
+
const addMcpServer = vi.fn();
|
|
40
|
+
const enableMcpServer = vi.fn().mockResolvedValue(void 0);
|
|
41
|
+
const getMcpServerStatus = vi.fn().mockReturnValueOnce({
|
|
42
|
+
name: "skill_echo_demo",
|
|
43
|
+
type: "stdio",
|
|
44
|
+
enabled: true,
|
|
45
|
+
status: "error",
|
|
46
|
+
error: "Request timed out"
|
|
47
|
+
}).mockReturnValueOnce({
|
|
48
|
+
name: "skill_echo_demo",
|
|
49
|
+
type: "stdio",
|
|
50
|
+
enabled: true,
|
|
51
|
+
status: "connected"
|
|
52
|
+
});
|
|
53
|
+
const tool = createInvokeSkillTool();
|
|
54
|
+
const result = await tool.execute(
|
|
55
|
+
{
|
|
56
|
+
skill: "echo-custom-mcp"
|
|
57
|
+
},
|
|
58
|
+
{
|
|
59
|
+
logger: {
|
|
60
|
+
warn: vi.fn()
|
|
61
|
+
},
|
|
62
|
+
services: {
|
|
63
|
+
prompts: promptManager
|
|
64
|
+
},
|
|
65
|
+
agent: {
|
|
66
|
+
addMcpServer,
|
|
67
|
+
getMcpServerStatus,
|
|
68
|
+
enableMcpServer
|
|
69
|
+
}
|
|
70
|
+
}
|
|
71
|
+
);
|
|
72
|
+
expect(addMcpServer).not.toHaveBeenCalled();
|
|
73
|
+
expect(enableMcpServer).toHaveBeenCalledWith("skill_echo_demo");
|
|
74
|
+
expect(getMcpServerStatus).toHaveBeenCalledTimes(2);
|
|
75
|
+
expect(result).toMatchObject({
|
|
76
|
+
skill: "config:echo-custom-mcp",
|
|
77
|
+
content: "Use the bundled echo MCP tool."
|
|
78
|
+
});
|
|
79
|
+
});
|
|
80
|
+
it("does not connect bundled MCP servers when fork execution is unavailable", async () => {
|
|
81
|
+
const promptInfo = createPromptInfo();
|
|
82
|
+
const promptManager = {
|
|
83
|
+
listAutoInvocablePrompts: vi.fn().mockResolvedValue({ "config:echo-custom-mcp": promptInfo }),
|
|
84
|
+
getPromptDefinition: vi.fn().mockResolvedValue({
|
|
85
|
+
name: "echo-custom-mcp",
|
|
86
|
+
context: "fork"
|
|
87
|
+
}),
|
|
88
|
+
getPrompt: vi.fn()
|
|
89
|
+
};
|
|
90
|
+
const addMcpServer = vi.fn();
|
|
91
|
+
const enableMcpServer = vi.fn();
|
|
92
|
+
const getMcpServerStatus = vi.fn();
|
|
93
|
+
const tool = createInvokeSkillTool();
|
|
94
|
+
const result = await tool.execute(
|
|
95
|
+
{
|
|
96
|
+
skill: "echo-custom-mcp"
|
|
97
|
+
},
|
|
98
|
+
{
|
|
99
|
+
logger: {
|
|
100
|
+
warn: vi.fn()
|
|
101
|
+
},
|
|
102
|
+
services: {
|
|
103
|
+
prompts: promptManager
|
|
104
|
+
},
|
|
105
|
+
agent: {
|
|
106
|
+
addMcpServer,
|
|
107
|
+
getMcpServerStatus,
|
|
108
|
+
enableMcpServer
|
|
109
|
+
}
|
|
110
|
+
}
|
|
111
|
+
);
|
|
112
|
+
expect(addMcpServer).not.toHaveBeenCalled();
|
|
113
|
+
expect(enableMcpServer).not.toHaveBeenCalled();
|
|
114
|
+
expect(getMcpServerStatus).not.toHaveBeenCalled();
|
|
115
|
+
expect(promptManager.getPrompt).not.toHaveBeenCalled();
|
|
116
|
+
expect(result).toEqual({
|
|
117
|
+
error: "Skill 'echo-custom-mcp' requires fork execution (context: fork), but agent spawning is not available.",
|
|
118
|
+
skill: "config:echo-custom-mcp"
|
|
119
|
+
});
|
|
120
|
+
});
|
|
121
|
+
});
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@dexto/tools-builtins",
|
|
3
|
-
"version": "1.6.
|
|
3
|
+
"version": "1.6.19",
|
|
4
4
|
"description": "Built-in tools factory for Dexto agents",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "./dist/index.js",
|
|
@@ -17,10 +17,10 @@
|
|
|
17
17
|
"builtins"
|
|
18
18
|
],
|
|
19
19
|
"dependencies": {
|
|
20
|
-
"undici": "^7.24.
|
|
20
|
+
"undici": "^7.24.6",
|
|
21
21
|
"zod": "^3.25.0",
|
|
22
|
-
"@dexto/agent-config": "1.6.
|
|
23
|
-
"@dexto/core": "1.6.
|
|
22
|
+
"@dexto/agent-config": "1.6.19",
|
|
23
|
+
"@dexto/core": "1.6.19"
|
|
24
24
|
},
|
|
25
25
|
"devDependencies": {
|
|
26
26
|
"tsup": "^8.0.0",
|