@dexto/agent-management 1.5.7 → 1.6.0
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/AgentFactory.cjs +5 -9
- package/dist/AgentFactory.d.ts +6 -5
- package/dist/AgentFactory.d.ts.map +1 -1
- package/dist/AgentFactory.js +5 -9
- package/dist/AgentManager.cjs +2 -2
- package/dist/AgentManager.d.ts +1 -1
- package/dist/AgentManager.d.ts.map +1 -1
- package/dist/AgentManager.js +4 -4
- package/dist/agent-creation.cjs +95 -0
- package/dist/agent-creation.d.ts +15 -0
- package/dist/agent-creation.d.ts.map +1 -0
- package/dist/agent-creation.js +78 -0
- package/dist/config/config-enrichment.cjs +2 -12
- package/dist/config/config-enrichment.d.ts +1 -1
- package/dist/config/config-enrichment.d.ts.map +1 -1
- package/dist/config/config-enrichment.js +2 -12
- package/dist/config/config-manager.cjs +4 -4
- package/dist/config/config-manager.d.ts +1 -1
- package/dist/config/config-manager.d.ts.map +1 -1
- package/dist/config/config-manager.js +3 -1
- package/dist/config/loader.d.ts +3 -3
- package/dist/config/loader.d.ts.map +1 -1
- package/dist/images/image-store.cjs +256 -0
- package/dist/images/image-store.d.ts +70 -0
- package/dist/images/image-store.d.ts.map +1 -0
- package/dist/images/image-store.js +210 -0
- package/dist/index.cjs +43 -2
- package/dist/index.d.ts +5 -2
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +43 -1
- package/dist/models/custom-models.cjs +1 -1
- package/dist/models/custom-models.d.ts +7 -7
- package/dist/models/custom-models.d.ts.map +1 -1
- package/dist/models/custom-models.js +1 -1
- package/dist/plugins/discover-plugins.cjs +15 -31
- package/dist/plugins/discover-plugins.d.ts.map +1 -1
- package/dist/plugins/discover-plugins.js +15 -31
- package/dist/plugins/discover-skills.cjs +4 -0
- package/dist/plugins/discover-skills.d.ts +6 -3
- package/dist/plugins/discover-skills.d.ts.map +1 -1
- package/dist/plugins/discover-skills.js +4 -0
- package/dist/plugins/index.cjs +0 -2
- package/dist/plugins/index.d.ts +5 -6
- package/dist/plugins/index.d.ts.map +1 -1
- package/dist/plugins/index.js +0 -2
- package/dist/plugins/list-plugins.cjs +3 -1
- package/dist/plugins/list-plugins.d.ts.map +1 -1
- package/dist/plugins/list-plugins.js +3 -1
- package/dist/plugins/load-plugin.cjs +0 -13
- package/dist/plugins/load-plugin.d.ts +3 -5
- package/dist/plugins/load-plugin.d.ts.map +1 -1
- package/dist/plugins/load-plugin.js +0 -13
- package/dist/plugins/schemas.cjs +1 -11
- package/dist/plugins/schemas.d.ts +14 -69
- package/dist/plugins/schemas.d.ts.map +1 -1
- package/dist/plugins/schemas.js +1 -10
- package/dist/plugins/types.d.ts +2 -20
- package/dist/plugins/types.d.ts.map +1 -1
- package/dist/plugins/validate-plugin.cjs +7 -37
- package/dist/plugins/validate-plugin.d.ts +6 -24
- package/dist/plugins/validate-plugin.d.ts.map +1 -1
- package/dist/plugins/validate-plugin.js +8 -38
- package/dist/preferences/errors.cjs +11 -0
- package/dist/preferences/errors.d.ts +1 -0
- package/dist/preferences/errors.d.ts.map +1 -1
- package/dist/preferences/errors.js +11 -0
- package/dist/preferences/loader.cjs +119 -6
- package/dist/preferences/loader.d.ts +21 -1
- package/dist/preferences/loader.d.ts.map +1 -1
- package/dist/preferences/loader.js +102 -1
- package/dist/preferences/schemas.cjs +12 -0
- package/dist/preferences/schemas.d.ts +38 -12
- package/dist/preferences/schemas.d.ts.map +1 -1
- package/dist/preferences/schemas.js +10 -0
- package/dist/registry/registry.d.ts +4 -44
- package/dist/registry/registry.d.ts.map +1 -1
- package/dist/runtime/AgentPool.d.ts +2 -2
- package/dist/runtime/AgentPool.d.ts.map +1 -1
- package/dist/runtime/AgentRuntime.cjs +20 -15
- package/dist/runtime/AgentRuntime.d.ts +2 -2
- package/dist/runtime/AgentRuntime.d.ts.map +1 -1
- package/dist/runtime/AgentRuntime.js +20 -15
- package/dist/runtime/approval-delegation.d.ts +2 -2
- package/dist/runtime/approval-delegation.d.ts.map +1 -1
- package/dist/runtime/schemas.d.ts +1 -1
- package/dist/runtime/types.d.ts +2 -1
- package/dist/runtime/types.d.ts.map +1 -1
- package/dist/{tool-provider → tool-factories/agent-spawner}/error-codes.d.ts +1 -1
- package/dist/tool-factories/agent-spawner/error-codes.d.ts.map +1 -0
- package/dist/{tool-provider → tool-factories/agent-spawner}/errors.d.ts +1 -1
- package/dist/tool-factories/agent-spawner/errors.d.ts.map +1 -0
- package/dist/tool-factories/agent-spawner/factory.cjs +290 -0
- package/dist/tool-factories/agent-spawner/factory.d.ts +4 -0
- package/dist/tool-factories/agent-spawner/factory.d.ts.map +1 -0
- package/dist/tool-factories/agent-spawner/factory.js +279 -0
- package/dist/{tool-provider → tool-factories/agent-spawner}/index.cjs +9 -9
- package/dist/{tool-provider → tool-factories/agent-spawner}/index.d.ts +3 -3
- package/dist/tool-factories/agent-spawner/index.d.ts.map +1 -0
- package/dist/{tool-provider → tool-factories/agent-spawner}/index.js +4 -4
- package/dist/{tool-provider → tool-factories/agent-spawner}/llm-resolution.cjs +1 -1
- package/dist/{tool-provider → tool-factories/agent-spawner}/llm-resolution.d.ts +4 -4
- package/dist/tool-factories/agent-spawner/llm-resolution.d.ts.map +1 -0
- package/dist/{tool-provider → tool-factories/agent-spawner}/llm-resolution.js +1 -1
- package/dist/{tool-provider/runtime-service.cjs → tool-factories/agent-spawner/runtime.cjs} +112 -73
- package/dist/{tool-provider/runtime-service.d.ts → tool-factories/agent-spawner/runtime.d.ts} +8 -6
- package/dist/tool-factories/agent-spawner/runtime.d.ts.map +1 -0
- package/dist/{tool-provider/runtime-service.js → tool-factories/agent-spawner/runtime.js} +98 -69
- package/dist/{tool-provider → tool-factories/agent-spawner}/schemas.cjs +2 -2
- package/dist/{tool-provider → tool-factories/agent-spawner}/schemas.d.ts +4 -4
- package/dist/tool-factories/agent-spawner/schemas.d.ts.map +1 -0
- package/dist/{tool-provider → tool-factories/agent-spawner}/schemas.js +2 -2
- package/dist/{tool-provider → tool-factories/agent-spawner}/spawn-agent-tool.cjs +8 -7
- package/dist/tool-factories/agent-spawner/spawn-agent-tool.d.ts +11 -0
- package/dist/tool-factories/agent-spawner/spawn-agent-tool.d.ts.map +1 -0
- package/dist/{tool-provider → tool-factories/agent-spawner}/spawn-agent-tool.js +8 -7
- package/dist/tool-factories/agent-spawner/types.d.ts.map +1 -0
- package/dist/utils/api-key-resolver.cjs +1 -1
- package/dist/utils/api-key-resolver.js +1 -1
- package/dist/utils/feature-flags.cjs +3 -1
- package/dist/utils/feature-flags.d.ts +2 -2
- package/dist/utils/feature-flags.d.ts.map +1 -1
- package/dist/utils/feature-flags.js +3 -1
- package/dist/writer.d.ts +2 -1
- package/dist/writer.d.ts.map +1 -1
- package/package.json +6 -3
- package/dist/tool-provider/error-codes.d.ts.map +0 -1
- package/dist/tool-provider/errors.d.ts.map +0 -1
- package/dist/tool-provider/index.d.ts.map +0 -1
- package/dist/tool-provider/llm-resolution.d.ts.map +0 -1
- package/dist/tool-provider/runtime-service.d.ts.map +0 -1
- package/dist/tool-provider/schemas.d.ts.map +0 -1
- package/dist/tool-provider/spawn-agent-tool.d.ts +0 -10
- package/dist/tool-provider/spawn-agent-tool.d.ts.map +0 -1
- package/dist/tool-provider/tool-provider.cjs +0 -46
- package/dist/tool-provider/tool-provider.d.ts +0 -24
- package/dist/tool-provider/tool-provider.d.ts.map +0 -1
- package/dist/tool-provider/tool-provider.js +0 -22
- package/dist/tool-provider/types.d.ts.map +0 -1
- /package/dist/{tool-provider → tool-factories/agent-spawner}/error-codes.cjs +0 -0
- /package/dist/{tool-provider → tool-factories/agent-spawner}/error-codes.js +0 -0
- /package/dist/{tool-provider → tool-factories/agent-spawner}/errors.cjs +0 -0
- /package/dist/{tool-provider → tool-factories/agent-spawner}/errors.js +0 -0
- /package/dist/{tool-provider → tool-factories/agent-spawner}/types.cjs +0 -0
- /package/dist/{tool-provider → tool-factories/agent-spawner}/types.d.ts +0 -0
- /package/dist/{tool-provider → tool-factories/agent-spawner}/types.js +0 -0
|
@@ -0,0 +1,290 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __defProp = Object.defineProperty;
|
|
3
|
+
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
4
|
+
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
5
|
+
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
6
|
+
var __export = (target, all) => {
|
|
7
|
+
for (var name in all)
|
|
8
|
+
__defProp(target, name, { get: all[name], enumerable: true });
|
|
9
|
+
};
|
|
10
|
+
var __copyProps = (to, from, except, desc) => {
|
|
11
|
+
if (from && typeof from === "object" || typeof from === "function") {
|
|
12
|
+
for (let key of __getOwnPropNames(from))
|
|
13
|
+
if (!__hasOwnProp.call(to, key) && key !== except)
|
|
14
|
+
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
|
|
15
|
+
}
|
|
16
|
+
return to;
|
|
17
|
+
};
|
|
18
|
+
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
|
19
|
+
var factory_exports = {};
|
|
20
|
+
__export(factory_exports, {
|
|
21
|
+
agentSpawnerToolsFactory: () => agentSpawnerToolsFactory
|
|
22
|
+
});
|
|
23
|
+
module.exports = __toCommonJS(factory_exports);
|
|
24
|
+
var import_core = require("@dexto/core");
|
|
25
|
+
var import_orchestration = require("@dexto/orchestration");
|
|
26
|
+
var import_schemas = require("./schemas.js");
|
|
27
|
+
var import_runtime = require("./runtime.js");
|
|
28
|
+
var import_spawn_agent_tool = require("./spawn-agent-tool.js");
|
|
29
|
+
function requireAgentContext(context) {
|
|
30
|
+
if (!context.agent) {
|
|
31
|
+
throw import_core.ToolError.configInvalid("agent-spawner tools require ToolExecutionContext.agent");
|
|
32
|
+
}
|
|
33
|
+
if (!context.services) {
|
|
34
|
+
throw import_core.ToolError.configInvalid("agent-spawner tools require ToolExecutionContext.services");
|
|
35
|
+
}
|
|
36
|
+
return { agent: context.agent, logger: context.logger, toolServices: context.services };
|
|
37
|
+
}
|
|
38
|
+
const agentSpawnerToolsFactory = {
|
|
39
|
+
configSchema: import_schemas.AgentSpawnerConfigSchema,
|
|
40
|
+
metadata: {
|
|
41
|
+
displayName: "Agent Spawner",
|
|
42
|
+
description: "Spawn sub-agents for task delegation",
|
|
43
|
+
category: "agents"
|
|
44
|
+
},
|
|
45
|
+
create: (config) => {
|
|
46
|
+
let state;
|
|
47
|
+
const attachTaskForker = (options) => {
|
|
48
|
+
const { toolServices, taskForker, logger } = options;
|
|
49
|
+
if (toolServices.taskForker !== taskForker) {
|
|
50
|
+
toolServices.taskForker = taskForker;
|
|
51
|
+
logger.debug(
|
|
52
|
+
"AgentSpawnerRuntime attached as taskForker for context:fork skill support"
|
|
53
|
+
);
|
|
54
|
+
}
|
|
55
|
+
};
|
|
56
|
+
const ensureToolsInitialized = (context) => {
|
|
57
|
+
const { agent, logger, toolServices } = requireAgentContext(context);
|
|
58
|
+
if (state && state.agent === agent && !state.abortController.signal.aborted) {
|
|
59
|
+
attachTaskForker({ toolServices, taskForker: state.runtime, logger });
|
|
60
|
+
return state.tools;
|
|
61
|
+
}
|
|
62
|
+
if (state && !state.abortController.signal.aborted) {
|
|
63
|
+
state.abortController.abort();
|
|
64
|
+
}
|
|
65
|
+
if (state) {
|
|
66
|
+
state.runtime.cleanup().catch(() => void 0);
|
|
67
|
+
}
|
|
68
|
+
state = void 0;
|
|
69
|
+
const signalBus = new import_orchestration.SignalBus();
|
|
70
|
+
const taskRegistry = new import_orchestration.TaskRegistry(signalBus);
|
|
71
|
+
const conditionEngine = new import_orchestration.ConditionEngine(taskRegistry, signalBus, logger);
|
|
72
|
+
const spawnerRuntime = new import_runtime.AgentSpawnerRuntime(agent, config, logger);
|
|
73
|
+
attachTaskForker({ toolServices, taskForker: spawnerRuntime, logger });
|
|
74
|
+
const taskSessions = /* @__PURE__ */ new Map();
|
|
75
|
+
const emitTasksUpdate = (sessionId) => {
|
|
76
|
+
const tasks = taskRegistry.list({
|
|
77
|
+
status: ["running", "completed", "failed", "cancelled"]
|
|
78
|
+
});
|
|
79
|
+
const scopedTasks = sessionId ? tasks.filter((task) => taskSessions.get(task.taskId) === sessionId) : tasks;
|
|
80
|
+
const runningCount = scopedTasks.filter((task) => task.status === "running").length;
|
|
81
|
+
agent.emit("service:event", {
|
|
82
|
+
service: "orchestration",
|
|
83
|
+
event: "tasks-updated",
|
|
84
|
+
sessionId: sessionId ?? "",
|
|
85
|
+
data: {
|
|
86
|
+
runningCount,
|
|
87
|
+
tasks: scopedTasks.map((task) => ({
|
|
88
|
+
taskId: task.taskId,
|
|
89
|
+
status: task.status,
|
|
90
|
+
...task.description !== void 0 && {
|
|
91
|
+
description: task.description
|
|
92
|
+
}
|
|
93
|
+
}))
|
|
94
|
+
}
|
|
95
|
+
});
|
|
96
|
+
};
|
|
97
|
+
const triggerBackgroundCompletion = (taskId, sessionId) => {
|
|
98
|
+
if (!sessionId) {
|
|
99
|
+
return;
|
|
100
|
+
}
|
|
101
|
+
agent.emit("tool:background-completed", {
|
|
102
|
+
toolCallId: taskId,
|
|
103
|
+
sessionId
|
|
104
|
+
});
|
|
105
|
+
const taskInfo = taskRegistry.getInfo(taskId);
|
|
106
|
+
const resultText = (() => {
|
|
107
|
+
if (taskInfo?.status === "failed") {
|
|
108
|
+
return taskInfo.error ?? "Unknown error.";
|
|
109
|
+
}
|
|
110
|
+
if (taskInfo?.result !== void 0) {
|
|
111
|
+
if (typeof taskInfo.result === "string") {
|
|
112
|
+
return taskInfo.result;
|
|
113
|
+
}
|
|
114
|
+
try {
|
|
115
|
+
return JSON.stringify(taskInfo.result, null, 2);
|
|
116
|
+
} catch {
|
|
117
|
+
return String(taskInfo.result ?? "<unserializable result>");
|
|
118
|
+
}
|
|
119
|
+
}
|
|
120
|
+
return "No result available.";
|
|
121
|
+
})();
|
|
122
|
+
const sanitizeCdata = (value) => value.replace(/\]\]>/g, "]]]]><![CDATA[>");
|
|
123
|
+
const safeDescription = taskInfo?.description ? sanitizeCdata(taskInfo.description) : null;
|
|
124
|
+
const safeResultText = sanitizeCdata(resultText);
|
|
125
|
+
const descriptionTag = safeDescription ? ` <description><![CDATA[${safeDescription}]]></description>
|
|
126
|
+
` : "";
|
|
127
|
+
const statusTag = taskInfo?.status ? ` <status>${taskInfo.status}</status>
|
|
128
|
+
` : "";
|
|
129
|
+
const content = [
|
|
130
|
+
{
|
|
131
|
+
type: "text",
|
|
132
|
+
text: `<background-task-completion>
|
|
133
|
+
<origin>task</origin>
|
|
134
|
+
<note>The following response was reported by the background task (not user input).</note>
|
|
135
|
+
<taskId>${taskId}</taskId>
|
|
136
|
+
` + statusTag + descriptionTag + ` <result><![CDATA[${safeResultText}]]></result>
|
|
137
|
+
</background-task-completion>`
|
|
138
|
+
}
|
|
139
|
+
];
|
|
140
|
+
agent.isSessionBusy(sessionId).then((isBusy) => {
|
|
141
|
+
if (isBusy) {
|
|
142
|
+
agent.queueMessage(sessionId, {
|
|
143
|
+
content,
|
|
144
|
+
kind: "background"
|
|
145
|
+
}).catch(() => void 0);
|
|
146
|
+
} else {
|
|
147
|
+
agent.emit("run:invoke", {
|
|
148
|
+
sessionId,
|
|
149
|
+
content,
|
|
150
|
+
source: "external",
|
|
151
|
+
metadata: { taskId }
|
|
152
|
+
});
|
|
153
|
+
agent.generate(content, sessionId).catch(() => void 0);
|
|
154
|
+
}
|
|
155
|
+
}).catch(() => {
|
|
156
|
+
});
|
|
157
|
+
};
|
|
158
|
+
const handleBackground = (event) => {
|
|
159
|
+
const taskId = event.toolCallId;
|
|
160
|
+
if (taskRegistry.has(taskId)) {
|
|
161
|
+
return;
|
|
162
|
+
}
|
|
163
|
+
if (event.sessionId) {
|
|
164
|
+
taskSessions.set(taskId, event.sessionId);
|
|
165
|
+
}
|
|
166
|
+
try {
|
|
167
|
+
taskRegistry.register(
|
|
168
|
+
{
|
|
169
|
+
type: "generic",
|
|
170
|
+
taskId,
|
|
171
|
+
description: event.description ?? `Tool ${event.toolName}`,
|
|
172
|
+
promise: event.promise
|
|
173
|
+
},
|
|
174
|
+
{
|
|
175
|
+
...event.timeoutMs !== void 0 && { timeout: event.timeoutMs },
|
|
176
|
+
...event.notifyOnComplete !== void 0 && {
|
|
177
|
+
notify: event.notifyOnComplete
|
|
178
|
+
}
|
|
179
|
+
}
|
|
180
|
+
);
|
|
181
|
+
} catch (error) {
|
|
182
|
+
taskSessions.delete(taskId);
|
|
183
|
+
event.promise.catch(() => void 0);
|
|
184
|
+
logger.warn(
|
|
185
|
+
`Failed to register background task ${taskId}: ${error instanceof Error ? error.message : String(error)}`,
|
|
186
|
+
{ color: "yellow" }
|
|
187
|
+
);
|
|
188
|
+
return;
|
|
189
|
+
}
|
|
190
|
+
emitTasksUpdate(event.sessionId);
|
|
191
|
+
event.promise.finally(() => {
|
|
192
|
+
taskSessions.delete(taskId);
|
|
193
|
+
emitTasksUpdate(event.sessionId);
|
|
194
|
+
triggerBackgroundCompletion(taskId, event.sessionId);
|
|
195
|
+
});
|
|
196
|
+
};
|
|
197
|
+
const abortController = new AbortController();
|
|
198
|
+
agent.on("tool:background", handleBackground, {
|
|
199
|
+
signal: abortController.signal
|
|
200
|
+
});
|
|
201
|
+
agent.on(
|
|
202
|
+
"agent:stopped",
|
|
203
|
+
() => {
|
|
204
|
+
spawnerRuntime.cleanup().catch(() => void 0);
|
|
205
|
+
abortController.abort();
|
|
206
|
+
},
|
|
207
|
+
{ signal: abortController.signal }
|
|
208
|
+
);
|
|
209
|
+
const spawnAgentTool = (0, import_spawn_agent_tool.createSpawnAgentTool)(spawnerRuntime);
|
|
210
|
+
const waitForTool = (0, import_orchestration.createWaitForTool)(conditionEngine);
|
|
211
|
+
const checkTaskTool = (0, import_orchestration.createCheckTaskTool)(taskRegistry);
|
|
212
|
+
const listTasksTool = (0, import_orchestration.createListTasksTool)(taskRegistry);
|
|
213
|
+
const tools = {
|
|
214
|
+
spawnAgent: spawnAgentTool,
|
|
215
|
+
waitFor: waitForTool,
|
|
216
|
+
checkTask: checkTaskTool,
|
|
217
|
+
listTasks: listTasksTool
|
|
218
|
+
};
|
|
219
|
+
state = {
|
|
220
|
+
agent,
|
|
221
|
+
abortController,
|
|
222
|
+
runtime: spawnerRuntime,
|
|
223
|
+
tools
|
|
224
|
+
};
|
|
225
|
+
return tools;
|
|
226
|
+
};
|
|
227
|
+
return [
|
|
228
|
+
{
|
|
229
|
+
id: "spawn_agent",
|
|
230
|
+
displayName: "Agent",
|
|
231
|
+
description: "Spawn a sub-agent to handle a task and return its result.",
|
|
232
|
+
inputSchema: import_schemas.SpawnAgentInputSchema,
|
|
233
|
+
execute: (input, context) => ensureToolsInitialized(context).spawnAgent.execute(input, context),
|
|
234
|
+
generatePreview: async (input, context) => {
|
|
235
|
+
const tool = ensureToolsInitialized(context).spawnAgent;
|
|
236
|
+
if (!tool.generatePreview) {
|
|
237
|
+
return null;
|
|
238
|
+
}
|
|
239
|
+
return await tool.generatePreview(input, context);
|
|
240
|
+
}
|
|
241
|
+
},
|
|
242
|
+
{
|
|
243
|
+
id: "wait_for",
|
|
244
|
+
displayName: "Wait",
|
|
245
|
+
description: "Wait for background task(s) to complete.",
|
|
246
|
+
inputSchema: import_orchestration.WaitForInputSchema,
|
|
247
|
+
execute: (input, context) => ensureToolsInitialized(context).waitFor.execute(input, context),
|
|
248
|
+
generatePreview: async (input, context) => {
|
|
249
|
+
const tool = ensureToolsInitialized(context).waitFor;
|
|
250
|
+
if (!tool.generatePreview) {
|
|
251
|
+
return null;
|
|
252
|
+
}
|
|
253
|
+
return await tool.generatePreview(input, context);
|
|
254
|
+
}
|
|
255
|
+
},
|
|
256
|
+
{
|
|
257
|
+
id: "check_task",
|
|
258
|
+
displayName: "Check Task",
|
|
259
|
+
description: "Check the status of a background task.",
|
|
260
|
+
inputSchema: import_orchestration.CheckTaskInputSchema,
|
|
261
|
+
execute: (input, context) => ensureToolsInitialized(context).checkTask.execute(input, context),
|
|
262
|
+
generatePreview: async (input, context) => {
|
|
263
|
+
const tool = ensureToolsInitialized(context).checkTask;
|
|
264
|
+
if (!tool.generatePreview) {
|
|
265
|
+
return null;
|
|
266
|
+
}
|
|
267
|
+
return await tool.generatePreview(input, context);
|
|
268
|
+
}
|
|
269
|
+
},
|
|
270
|
+
{
|
|
271
|
+
id: "list_tasks",
|
|
272
|
+
displayName: "List Tasks",
|
|
273
|
+
description: "List background tasks and their statuses.",
|
|
274
|
+
inputSchema: import_orchestration.ListTasksInputSchema,
|
|
275
|
+
execute: (input, context) => ensureToolsInitialized(context).listTasks.execute(input, context),
|
|
276
|
+
generatePreview: async (input, context) => {
|
|
277
|
+
const tool = ensureToolsInitialized(context).listTasks;
|
|
278
|
+
if (!tool.generatePreview) {
|
|
279
|
+
return null;
|
|
280
|
+
}
|
|
281
|
+
return await tool.generatePreview(input, context);
|
|
282
|
+
}
|
|
283
|
+
}
|
|
284
|
+
];
|
|
285
|
+
}
|
|
286
|
+
};
|
|
287
|
+
// Annotate the CommonJS export names for ESM import in node:
|
|
288
|
+
0 && (module.exports = {
|
|
289
|
+
agentSpawnerToolsFactory
|
|
290
|
+
});
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"factory.d.ts","sourceRoot":"","sources":["../../../src/tool-factories/agent-spawner/factory.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,qBAAqB,CAAC;AAevD,OAAO,EAGH,KAAK,kBAAkB,EAC1B,MAAM,cAAc,CAAC;AAkCtB,eAAO,MAAM,wBAAwB,EAAE,WAAW,CAAC,kBAAkB,CA8SpE,CAAC"}
|
|
@@ -0,0 +1,279 @@
|
|
|
1
|
+
import { ToolError } from "@dexto/core";
|
|
2
|
+
import {
|
|
3
|
+
ConditionEngine,
|
|
4
|
+
SignalBus,
|
|
5
|
+
TaskRegistry,
|
|
6
|
+
createCheckTaskTool,
|
|
7
|
+
createListTasksTool,
|
|
8
|
+
createWaitForTool,
|
|
9
|
+
WaitForInputSchema,
|
|
10
|
+
CheckTaskInputSchema,
|
|
11
|
+
ListTasksInputSchema
|
|
12
|
+
} from "@dexto/orchestration";
|
|
13
|
+
import {
|
|
14
|
+
AgentSpawnerConfigSchema,
|
|
15
|
+
SpawnAgentInputSchema
|
|
16
|
+
} from "./schemas.js";
|
|
17
|
+
import { AgentSpawnerRuntime } from "./runtime.js";
|
|
18
|
+
import { createSpawnAgentTool } from "./spawn-agent-tool.js";
|
|
19
|
+
function requireAgentContext(context) {
|
|
20
|
+
if (!context.agent) {
|
|
21
|
+
throw ToolError.configInvalid("agent-spawner tools require ToolExecutionContext.agent");
|
|
22
|
+
}
|
|
23
|
+
if (!context.services) {
|
|
24
|
+
throw ToolError.configInvalid("agent-spawner tools require ToolExecutionContext.services");
|
|
25
|
+
}
|
|
26
|
+
return { agent: context.agent, logger: context.logger, toolServices: context.services };
|
|
27
|
+
}
|
|
28
|
+
const agentSpawnerToolsFactory = {
|
|
29
|
+
configSchema: AgentSpawnerConfigSchema,
|
|
30
|
+
metadata: {
|
|
31
|
+
displayName: "Agent Spawner",
|
|
32
|
+
description: "Spawn sub-agents for task delegation",
|
|
33
|
+
category: "agents"
|
|
34
|
+
},
|
|
35
|
+
create: (config) => {
|
|
36
|
+
let state;
|
|
37
|
+
const attachTaskForker = (options) => {
|
|
38
|
+
const { toolServices, taskForker, logger } = options;
|
|
39
|
+
if (toolServices.taskForker !== taskForker) {
|
|
40
|
+
toolServices.taskForker = taskForker;
|
|
41
|
+
logger.debug(
|
|
42
|
+
"AgentSpawnerRuntime attached as taskForker for context:fork skill support"
|
|
43
|
+
);
|
|
44
|
+
}
|
|
45
|
+
};
|
|
46
|
+
const ensureToolsInitialized = (context) => {
|
|
47
|
+
const { agent, logger, toolServices } = requireAgentContext(context);
|
|
48
|
+
if (state && state.agent === agent && !state.abortController.signal.aborted) {
|
|
49
|
+
attachTaskForker({ toolServices, taskForker: state.runtime, logger });
|
|
50
|
+
return state.tools;
|
|
51
|
+
}
|
|
52
|
+
if (state && !state.abortController.signal.aborted) {
|
|
53
|
+
state.abortController.abort();
|
|
54
|
+
}
|
|
55
|
+
if (state) {
|
|
56
|
+
state.runtime.cleanup().catch(() => void 0);
|
|
57
|
+
}
|
|
58
|
+
state = void 0;
|
|
59
|
+
const signalBus = new SignalBus();
|
|
60
|
+
const taskRegistry = new TaskRegistry(signalBus);
|
|
61
|
+
const conditionEngine = new ConditionEngine(taskRegistry, signalBus, logger);
|
|
62
|
+
const spawnerRuntime = new AgentSpawnerRuntime(agent, config, logger);
|
|
63
|
+
attachTaskForker({ toolServices, taskForker: spawnerRuntime, logger });
|
|
64
|
+
const taskSessions = /* @__PURE__ */ new Map();
|
|
65
|
+
const emitTasksUpdate = (sessionId) => {
|
|
66
|
+
const tasks = taskRegistry.list({
|
|
67
|
+
status: ["running", "completed", "failed", "cancelled"]
|
|
68
|
+
});
|
|
69
|
+
const scopedTasks = sessionId ? tasks.filter((task) => taskSessions.get(task.taskId) === sessionId) : tasks;
|
|
70
|
+
const runningCount = scopedTasks.filter((task) => task.status === "running").length;
|
|
71
|
+
agent.emit("service:event", {
|
|
72
|
+
service: "orchestration",
|
|
73
|
+
event: "tasks-updated",
|
|
74
|
+
sessionId: sessionId ?? "",
|
|
75
|
+
data: {
|
|
76
|
+
runningCount,
|
|
77
|
+
tasks: scopedTasks.map((task) => ({
|
|
78
|
+
taskId: task.taskId,
|
|
79
|
+
status: task.status,
|
|
80
|
+
...task.description !== void 0 && {
|
|
81
|
+
description: task.description
|
|
82
|
+
}
|
|
83
|
+
}))
|
|
84
|
+
}
|
|
85
|
+
});
|
|
86
|
+
};
|
|
87
|
+
const triggerBackgroundCompletion = (taskId, sessionId) => {
|
|
88
|
+
if (!sessionId) {
|
|
89
|
+
return;
|
|
90
|
+
}
|
|
91
|
+
agent.emit("tool:background-completed", {
|
|
92
|
+
toolCallId: taskId,
|
|
93
|
+
sessionId
|
|
94
|
+
});
|
|
95
|
+
const taskInfo = taskRegistry.getInfo(taskId);
|
|
96
|
+
const resultText = (() => {
|
|
97
|
+
if (taskInfo?.status === "failed") {
|
|
98
|
+
return taskInfo.error ?? "Unknown error.";
|
|
99
|
+
}
|
|
100
|
+
if (taskInfo?.result !== void 0) {
|
|
101
|
+
if (typeof taskInfo.result === "string") {
|
|
102
|
+
return taskInfo.result;
|
|
103
|
+
}
|
|
104
|
+
try {
|
|
105
|
+
return JSON.stringify(taskInfo.result, null, 2);
|
|
106
|
+
} catch {
|
|
107
|
+
return String(taskInfo.result ?? "<unserializable result>");
|
|
108
|
+
}
|
|
109
|
+
}
|
|
110
|
+
return "No result available.";
|
|
111
|
+
})();
|
|
112
|
+
const sanitizeCdata = (value) => value.replace(/\]\]>/g, "]]]]><![CDATA[>");
|
|
113
|
+
const safeDescription = taskInfo?.description ? sanitizeCdata(taskInfo.description) : null;
|
|
114
|
+
const safeResultText = sanitizeCdata(resultText);
|
|
115
|
+
const descriptionTag = safeDescription ? ` <description><![CDATA[${safeDescription}]]></description>
|
|
116
|
+
` : "";
|
|
117
|
+
const statusTag = taskInfo?.status ? ` <status>${taskInfo.status}</status>
|
|
118
|
+
` : "";
|
|
119
|
+
const content = [
|
|
120
|
+
{
|
|
121
|
+
type: "text",
|
|
122
|
+
text: `<background-task-completion>
|
|
123
|
+
<origin>task</origin>
|
|
124
|
+
<note>The following response was reported by the background task (not user input).</note>
|
|
125
|
+
<taskId>${taskId}</taskId>
|
|
126
|
+
` + statusTag + descriptionTag + ` <result><![CDATA[${safeResultText}]]></result>
|
|
127
|
+
</background-task-completion>`
|
|
128
|
+
}
|
|
129
|
+
];
|
|
130
|
+
agent.isSessionBusy(sessionId).then((isBusy) => {
|
|
131
|
+
if (isBusy) {
|
|
132
|
+
agent.queueMessage(sessionId, {
|
|
133
|
+
content,
|
|
134
|
+
kind: "background"
|
|
135
|
+
}).catch(() => void 0);
|
|
136
|
+
} else {
|
|
137
|
+
agent.emit("run:invoke", {
|
|
138
|
+
sessionId,
|
|
139
|
+
content,
|
|
140
|
+
source: "external",
|
|
141
|
+
metadata: { taskId }
|
|
142
|
+
});
|
|
143
|
+
agent.generate(content, sessionId).catch(() => void 0);
|
|
144
|
+
}
|
|
145
|
+
}).catch(() => {
|
|
146
|
+
});
|
|
147
|
+
};
|
|
148
|
+
const handleBackground = (event) => {
|
|
149
|
+
const taskId = event.toolCallId;
|
|
150
|
+
if (taskRegistry.has(taskId)) {
|
|
151
|
+
return;
|
|
152
|
+
}
|
|
153
|
+
if (event.sessionId) {
|
|
154
|
+
taskSessions.set(taskId, event.sessionId);
|
|
155
|
+
}
|
|
156
|
+
try {
|
|
157
|
+
taskRegistry.register(
|
|
158
|
+
{
|
|
159
|
+
type: "generic",
|
|
160
|
+
taskId,
|
|
161
|
+
description: event.description ?? `Tool ${event.toolName}`,
|
|
162
|
+
promise: event.promise
|
|
163
|
+
},
|
|
164
|
+
{
|
|
165
|
+
...event.timeoutMs !== void 0 && { timeout: event.timeoutMs },
|
|
166
|
+
...event.notifyOnComplete !== void 0 && {
|
|
167
|
+
notify: event.notifyOnComplete
|
|
168
|
+
}
|
|
169
|
+
}
|
|
170
|
+
);
|
|
171
|
+
} catch (error) {
|
|
172
|
+
taskSessions.delete(taskId);
|
|
173
|
+
event.promise.catch(() => void 0);
|
|
174
|
+
logger.warn(
|
|
175
|
+
`Failed to register background task ${taskId}: ${error instanceof Error ? error.message : String(error)}`,
|
|
176
|
+
{ color: "yellow" }
|
|
177
|
+
);
|
|
178
|
+
return;
|
|
179
|
+
}
|
|
180
|
+
emitTasksUpdate(event.sessionId);
|
|
181
|
+
event.promise.finally(() => {
|
|
182
|
+
taskSessions.delete(taskId);
|
|
183
|
+
emitTasksUpdate(event.sessionId);
|
|
184
|
+
triggerBackgroundCompletion(taskId, event.sessionId);
|
|
185
|
+
});
|
|
186
|
+
};
|
|
187
|
+
const abortController = new AbortController();
|
|
188
|
+
agent.on("tool:background", handleBackground, {
|
|
189
|
+
signal: abortController.signal
|
|
190
|
+
});
|
|
191
|
+
agent.on(
|
|
192
|
+
"agent:stopped",
|
|
193
|
+
() => {
|
|
194
|
+
spawnerRuntime.cleanup().catch(() => void 0);
|
|
195
|
+
abortController.abort();
|
|
196
|
+
},
|
|
197
|
+
{ signal: abortController.signal }
|
|
198
|
+
);
|
|
199
|
+
const spawnAgentTool = createSpawnAgentTool(spawnerRuntime);
|
|
200
|
+
const waitForTool = createWaitForTool(conditionEngine);
|
|
201
|
+
const checkTaskTool = createCheckTaskTool(taskRegistry);
|
|
202
|
+
const listTasksTool = createListTasksTool(taskRegistry);
|
|
203
|
+
const tools = {
|
|
204
|
+
spawnAgent: spawnAgentTool,
|
|
205
|
+
waitFor: waitForTool,
|
|
206
|
+
checkTask: checkTaskTool,
|
|
207
|
+
listTasks: listTasksTool
|
|
208
|
+
};
|
|
209
|
+
state = {
|
|
210
|
+
agent,
|
|
211
|
+
abortController,
|
|
212
|
+
runtime: spawnerRuntime,
|
|
213
|
+
tools
|
|
214
|
+
};
|
|
215
|
+
return tools;
|
|
216
|
+
};
|
|
217
|
+
return [
|
|
218
|
+
{
|
|
219
|
+
id: "spawn_agent",
|
|
220
|
+
displayName: "Agent",
|
|
221
|
+
description: "Spawn a sub-agent to handle a task and return its result.",
|
|
222
|
+
inputSchema: SpawnAgentInputSchema,
|
|
223
|
+
execute: (input, context) => ensureToolsInitialized(context).spawnAgent.execute(input, context),
|
|
224
|
+
generatePreview: async (input, context) => {
|
|
225
|
+
const tool = ensureToolsInitialized(context).spawnAgent;
|
|
226
|
+
if (!tool.generatePreview) {
|
|
227
|
+
return null;
|
|
228
|
+
}
|
|
229
|
+
return await tool.generatePreview(input, context);
|
|
230
|
+
}
|
|
231
|
+
},
|
|
232
|
+
{
|
|
233
|
+
id: "wait_for",
|
|
234
|
+
displayName: "Wait",
|
|
235
|
+
description: "Wait for background task(s) to complete.",
|
|
236
|
+
inputSchema: WaitForInputSchema,
|
|
237
|
+
execute: (input, context) => ensureToolsInitialized(context).waitFor.execute(input, context),
|
|
238
|
+
generatePreview: async (input, context) => {
|
|
239
|
+
const tool = ensureToolsInitialized(context).waitFor;
|
|
240
|
+
if (!tool.generatePreview) {
|
|
241
|
+
return null;
|
|
242
|
+
}
|
|
243
|
+
return await tool.generatePreview(input, context);
|
|
244
|
+
}
|
|
245
|
+
},
|
|
246
|
+
{
|
|
247
|
+
id: "check_task",
|
|
248
|
+
displayName: "Check Task",
|
|
249
|
+
description: "Check the status of a background task.",
|
|
250
|
+
inputSchema: CheckTaskInputSchema,
|
|
251
|
+
execute: (input, context) => ensureToolsInitialized(context).checkTask.execute(input, context),
|
|
252
|
+
generatePreview: async (input, context) => {
|
|
253
|
+
const tool = ensureToolsInitialized(context).checkTask;
|
|
254
|
+
if (!tool.generatePreview) {
|
|
255
|
+
return null;
|
|
256
|
+
}
|
|
257
|
+
return await tool.generatePreview(input, context);
|
|
258
|
+
}
|
|
259
|
+
},
|
|
260
|
+
{
|
|
261
|
+
id: "list_tasks",
|
|
262
|
+
displayName: "List Tasks",
|
|
263
|
+
description: "List background tasks and their statuses.",
|
|
264
|
+
inputSchema: ListTasksInputSchema,
|
|
265
|
+
execute: (input, context) => ensureToolsInitialized(context).listTasks.execute(input, context),
|
|
266
|
+
generatePreview: async (input, context) => {
|
|
267
|
+
const tool = ensureToolsInitialized(context).listTasks;
|
|
268
|
+
if (!tool.generatePreview) {
|
|
269
|
+
return null;
|
|
270
|
+
}
|
|
271
|
+
return await tool.generatePreview(input, context);
|
|
272
|
+
}
|
|
273
|
+
}
|
|
274
|
+
];
|
|
275
|
+
}
|
|
276
|
+
};
|
|
277
|
+
export {
|
|
278
|
+
agentSpawnerToolsFactory
|
|
279
|
+
};
|
|
@@ -16,20 +16,20 @@ var __copyProps = (to, from, except, desc) => {
|
|
|
16
16
|
return to;
|
|
17
17
|
};
|
|
18
18
|
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
|
19
|
-
var
|
|
20
|
-
__export(
|
|
19
|
+
var agent_spawner_exports = {};
|
|
20
|
+
__export(agent_spawner_exports, {
|
|
21
21
|
AgentSpawnerConfigSchema: () => import_schemas.AgentSpawnerConfigSchema,
|
|
22
22
|
AgentSpawnerError: () => import_errors.AgentSpawnerError,
|
|
23
23
|
AgentSpawnerErrorCode: () => import_error_codes.AgentSpawnerErrorCode,
|
|
24
|
-
|
|
24
|
+
AgentSpawnerRuntime: () => import_runtime.AgentSpawnerRuntime,
|
|
25
25
|
SpawnAgentInputSchema: () => import_schemas2.SpawnAgentInputSchema,
|
|
26
|
-
|
|
26
|
+
agentSpawnerToolsFactory: () => import_factory.agentSpawnerToolsFactory,
|
|
27
27
|
createSpawnAgentTool: () => import_spawn_agent_tool.createSpawnAgentTool
|
|
28
28
|
});
|
|
29
|
-
module.exports = __toCommonJS(
|
|
30
|
-
var
|
|
29
|
+
module.exports = __toCommonJS(agent_spawner_exports);
|
|
30
|
+
var import_factory = require("./factory.js");
|
|
31
31
|
var import_schemas = require("./schemas.js");
|
|
32
|
-
var
|
|
32
|
+
var import_runtime = require("./runtime.js");
|
|
33
33
|
var import_spawn_agent_tool = require("./spawn-agent-tool.js");
|
|
34
34
|
var import_schemas2 = require("./schemas.js");
|
|
35
35
|
var import_errors = require("./errors.js");
|
|
@@ -39,8 +39,8 @@ var import_error_codes = require("./error-codes.js");
|
|
|
39
39
|
AgentSpawnerConfigSchema,
|
|
40
40
|
AgentSpawnerError,
|
|
41
41
|
AgentSpawnerErrorCode,
|
|
42
|
-
|
|
42
|
+
AgentSpawnerRuntime,
|
|
43
43
|
SpawnAgentInputSchema,
|
|
44
|
-
|
|
44
|
+
agentSpawnerToolsFactory,
|
|
45
45
|
createSpawnAgentTool
|
|
46
46
|
});
|
|
@@ -1,12 +1,12 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* Agent Spawner
|
|
2
|
+
* Agent Spawner Tools Factory
|
|
3
3
|
*
|
|
4
4
|
* Enables agents to spawn sub-agents for task delegation.
|
|
5
5
|
*/
|
|
6
|
-
export {
|
|
6
|
+
export { agentSpawnerToolsFactory } from './factory.js';
|
|
7
7
|
export { AgentSpawnerConfigSchema } from './schemas.js';
|
|
8
8
|
export type { AgentSpawnerConfig } from './schemas.js';
|
|
9
|
-
export {
|
|
9
|
+
export { AgentSpawnerRuntime } from './runtime.js';
|
|
10
10
|
export { createSpawnAgentTool } from './spawn-agent-tool.js';
|
|
11
11
|
export { SpawnAgentInputSchema } from './schemas.js';
|
|
12
12
|
export type { SpawnAgentInput } from './schemas.js';
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/tool-factories/agent-spawner/index.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAGH,OAAO,EAAE,wBAAwB,EAAE,MAAM,cAAc,CAAC;AAGxD,OAAO,EAAE,wBAAwB,EAAE,MAAM,cAAc,CAAC;AACxD,YAAY,EAAE,kBAAkB,EAAE,MAAM,cAAc,CAAC;AAGvD,OAAO,EAAE,mBAAmB,EAAE,MAAM,cAAc,CAAC;AAGnD,OAAO,EAAE,oBAAoB,EAAE,MAAM,uBAAuB,CAAC;AAG7D,OAAO,EAAE,qBAAqB,EAAE,MAAM,cAAc,CAAC;AACrD,YAAY,EAAE,eAAe,EAAE,MAAM,cAAc,CAAC;AAGpD,YAAY,EAAE,gBAAgB,EAAE,MAAM,YAAY,CAAC;AAGnD,OAAO,EAAE,iBAAiB,EAAE,MAAM,aAAa,CAAC;AAChD,OAAO,EAAE,qBAAqB,EAAE,MAAM,kBAAkB,CAAC"}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { agentSpawnerToolsFactory } from "./factory.js";
|
|
2
2
|
import { AgentSpawnerConfigSchema } from "./schemas.js";
|
|
3
|
-
import {
|
|
3
|
+
import { AgentSpawnerRuntime } from "./runtime.js";
|
|
4
4
|
import { createSpawnAgentTool } from "./spawn-agent-tool.js";
|
|
5
5
|
import { SpawnAgentInputSchema } from "./schemas.js";
|
|
6
6
|
import { AgentSpawnerError } from "./errors.js";
|
|
@@ -9,8 +9,8 @@ export {
|
|
|
9
9
|
AgentSpawnerConfigSchema,
|
|
10
10
|
AgentSpawnerError,
|
|
11
11
|
AgentSpawnerErrorCode,
|
|
12
|
-
|
|
12
|
+
AgentSpawnerRuntime,
|
|
13
13
|
SpawnAgentInputSchema,
|
|
14
|
-
|
|
14
|
+
agentSpawnerToolsFactory,
|
|
15
15
|
createSpawnAgentTool
|
|
16
16
|
};
|
|
@@ -65,7 +65,7 @@ function resolveSubAgentLLM(options) {
|
|
|
65
65
|
return {
|
|
66
66
|
llm: parentLLM,
|
|
67
67
|
resolution: "parent-fallback",
|
|
68
|
-
reason: `${agentLabel} cannot use ${subAgentProvider}/${subAgentModel} with parent's ${parentProvider} provider. Falling back to parent's LLM config. Tip: Use 'dexto login' for Dexto Credits which supports all models.`
|
|
68
|
+
reason: `${agentLabel} cannot use ${subAgentProvider}/${subAgentModel} with parent's ${parentProvider} provider. Falling back to parent's LLM config. Tip: Use 'dexto login' for Dexto Nova Credits which supports all models.`
|
|
69
69
|
};
|
|
70
70
|
}
|
|
71
71
|
// Annotate the CommonJS export names for ESM import in node:
|