plugin-agent-orchestrator 1.0.17 → 1.0.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/client/AIEmployeeSelect.d.ts +11 -0
- package/dist/client/AIEmployeesContext.d.ts +30 -0
- package/dist/client/AgentRunsTab.d.ts +2 -0
- package/dist/client/HarnessProfilesTab.d.ts +2 -0
- package/dist/client/OrchestratorSettings.d.ts +3 -0
- package/dist/client/RulesTab.d.ts +2 -0
- package/dist/client/TracingTab.d.ts +2 -0
- package/dist/client/index.d.ts +1 -0
- package/dist/client/index.js +1 -1
- package/dist/client/plugin.d.ts +6 -0
- package/dist/client/skill-hub/components/ExecutionHistory.d.ts +2 -0
- package/dist/client/skill-hub/components/ExecutionProgress.d.ts +20 -0
- package/dist/client/skill-hub/components/GitSkillImport.d.ts +7 -0
- package/dist/client/skill-hub/components/LoopSettings.d.ts +2 -0
- package/dist/client/skill-hub/components/SkillEditor.d.ts +7 -0
- package/dist/client/skill-hub/components/SkillManager.d.ts +2 -0
- package/dist/client/skill-hub/components/SkillMetrics.d.ts +2 -0
- package/dist/client/skill-hub/components/SkillTestPanel.d.ts +7 -0
- package/dist/client/skill-hub/index.d.ts +11 -0
- package/dist/client/skill-hub/locale.d.ts +3 -0
- package/dist/client/skill-hub/tools/InteractionSchemasProvider.d.ts +6 -0
- package/dist/client/skill-hub/tools/SkillHubCard.d.ts +3 -0
- package/dist/client/skill-hub/tools/loopTemplates.d.ts +22 -0
- package/dist/client/skill-hub/tools/registerSkillLoopCards.d.ts +1 -0
- package/dist/client/skill-hub/utils/jsonFields.d.ts +3 -0
- package/dist/client/tools/PlanApprovalCard.d.ts +3 -0
- package/dist/client/tools/registerOrchestratorCards.d.ts +1 -0
- package/dist/externalVersion.js +6 -6
- package/dist/index.d.ts +2 -0
- package/dist/server/collections/agent-execution-spans.d.ts +9 -0
- package/dist/server/collections/agent-harness-profiles.d.ts +2 -0
- package/dist/server/collections/agent-harness-profiles.js +89 -0
- package/dist/server/collections/agent-loop-events.d.ts +2 -0
- package/dist/server/collections/agent-loop-events.js +101 -0
- package/dist/server/collections/agent-loop-runs.d.ts +2 -0
- package/dist/server/collections/agent-loop-runs.js +188 -0
- package/dist/server/collections/agent-loop-steps.d.ts +2 -0
- package/dist/server/collections/agent-loop-steps.js +174 -0
- package/dist/server/collections/orchestrator-config.d.ts +2 -0
- package/dist/server/collections/orchestrator-config.js +7 -0
- package/dist/server/collections/orchestrator-logs.d.ts +8 -0
- package/dist/server/collections/skill-definitions.d.ts +3 -0
- package/dist/server/collections/skill-executions.d.ts +3 -0
- package/dist/server/collections/skill-executions.js +12 -0
- package/dist/server/collections/skill-loop-configs.d.ts +3 -0
- package/dist/server/collections/skill-loop-configs.js +94 -0
- package/dist/server/collections/skill-worker-configs.d.ts +3 -0
- package/dist/server/index.d.ts +1 -0
- package/dist/server/migrations/20260423000000-add-progress-fields.d.ts +4 -0
- package/dist/server/migrations/20260425000000-add-interaction-schema.d.ts +4 -0
- package/dist/server/migrations/20260427000000-add-tracing-detail-fields.d.ts +7 -0
- package/dist/server/migrations/20260427000000-change-packages-to-text.d.ts +4 -0
- package/dist/server/migrations/20260427000001-change-other-json-to-text.d.ts +4 -0
- package/dist/server/migrations/20260429000000-add-llm-fields.d.ts +7 -0
- package/dist/server/migrations/20260429000000-fix-inputargs-json-to-text.d.ts +16 -0
- package/dist/server/migrations/20260503000000-add-orchestrator-trace-fields.d.ts +7 -0
- package/dist/server/migrations/20260524000000-add-agent-loop-fields-to-skill-executions.d.ts +7 -0
- package/dist/server/migrations/20260524000000-add-agent-loop-fields-to-skill-executions.js +55 -0
- package/dist/server/migrations/20260524001000-add-plan-approval-and-harness-profiles.d.ts +12 -0
- package/dist/server/migrations/20260524001000-add-plan-approval-and-harness-profiles.js +162 -0
- package/dist/server/plugin.d.ts +16 -0
- package/dist/server/plugin.js +13 -0
- package/dist/server/resources/agent-loop.d.ts +3 -0
- package/dist/server/resources/agent-loop.js +205 -0
- package/dist/server/resources/tracing.d.ts +7 -0
- package/dist/server/services/AgentHarness.d.ts +42 -0
- package/dist/server/services/AgentHarness.js +565 -0
- package/dist/server/services/AgentLoopController.d.ts +205 -0
- package/dist/server/services/AgentLoopController.js +940 -0
- package/dist/server/services/AgentLoopRepository.d.ts +20 -0
- package/dist/server/services/AgentLoopRepository.js +210 -0
- package/dist/server/services/AgentLoopService.d.ts +149 -0
- package/dist/server/services/AgentLoopService.js +133 -0
- package/dist/server/services/AgentPlanValidator.d.ts +4 -0
- package/dist/server/services/AgentPlanValidator.js +99 -0
- package/dist/server/services/AgentPlannerService.d.ts +8 -0
- package/dist/server/services/AgentPlannerService.js +119 -0
- package/dist/server/services/AgentRegistryService.d.ts +13 -0
- package/dist/server/services/AgentRegistryService.js +178 -0
- package/dist/server/services/CodeValidator.d.ts +32 -0
- package/dist/server/services/ExecutionSpanService.d.ts +46 -0
- package/dist/server/services/FileManager.d.ts +28 -0
- package/dist/server/services/SandboxRunner.d.ts +41 -0
- package/dist/server/services/SkillManager.d.ts +6 -0
- package/dist/server/services/SkillRepositoryService.d.ts +22 -0
- package/dist/server/services/WorkerEnvManager.d.ts +26 -0
- package/dist/server/skill-hub/actions/git-import.d.ts +21 -0
- package/dist/server/skill-hub/mcp/McpController.d.ts +15 -0
- package/dist/server/skill-hub/plugin.d.ts +61 -0
- package/dist/server/skill-hub/plugin.js +152 -54
- package/dist/server/skill-hub/tasks/SkillExecutionTask.d.ts +16 -0
- package/dist/server/skill-hub/tasks/SkillExecutionTask.js +15 -0
- package/dist/server/skill-hub/utils/json-fields.d.ts +7 -0
- package/dist/server/tools/agent-loop.d.ts +235 -0
- package/dist/server/tools/agent-loop.js +406 -0
- package/dist/server/tools/delegate-task.d.ts +19 -0
- package/dist/server/tools/delegate-task.js +19 -368
- package/dist/server/tools/external-rag-search.d.ts +42 -0
- package/dist/server/tools/orchestrator-plan.d.ts +205 -0
- package/dist/server/tools/orchestrator-plan.js +291 -0
- package/dist/server/tools/skill-execute.d.ts +36 -0
- package/dist/server/tools/skill-execute.js +2 -0
- package/package.json +1 -1
- package/src/client/AgentRunsTab.tsx +764 -0
- package/src/client/HarnessProfilesTab.tsx +247 -0
- package/src/client/OrchestratorSettings.tsx +40 -2
- package/src/client/RulesTab.tsx +103 -6
- package/src/client/plugin.tsx +27 -54
- package/src/client/skill-hub/components/LoopSettings.tsx +331 -0
- package/src/client/skill-hub/index.tsx +51 -75
- package/src/client/skill-hub/tools/InteractionSchemasProvider.tsx +56 -16
- package/src/client/skill-hub/tools/SkillHubCard.tsx +35 -4
- package/src/client/skill-hub/tools/loopTemplates.ts +52 -0
- package/src/client/skill-hub/tools/registerSkillLoopCards.ts +58 -0
- package/src/client/tools/PlanApprovalCard.tsx +175 -0
- package/src/client/tools/registerOrchestratorCards.ts +7 -0
- package/src/server/collections/agent-harness-profiles.ts +59 -0
- package/src/server/collections/agent-loop-events.ts +71 -0
- package/src/server/collections/agent-loop-runs.ts +158 -0
- package/src/server/collections/agent-loop-steps.ts +144 -0
- package/src/server/collections/orchestrator-config.ts +7 -0
- package/src/server/collections/skill-executions.ts +63 -51
- package/src/server/collections/skill-loop-configs.ts +65 -0
- package/src/server/migrations/20260524000000-add-agent-loop-fields-to-skill-executions.ts +30 -0
- package/src/server/migrations/20260524001000-add-plan-approval-and-harness-profiles.ts +142 -0
- package/src/server/plugin.ts +15 -0
- package/src/server/resources/agent-loop.ts +183 -0
- package/src/server/services/AgentHarness.ts +663 -0
- package/src/server/services/AgentLoopController.ts +1128 -0
- package/src/server/services/AgentLoopRepository.ts +194 -0
- package/src/server/services/AgentLoopService.ts +161 -0
- package/src/server/services/AgentPlanValidator.ts +73 -0
- package/src/server/services/AgentPlannerService.ts +93 -0
- package/src/server/services/AgentRegistryService.ts +169 -0
- package/src/server/services/ExecutionSpanService.ts +2 -0
- package/src/server/skill-hub/plugin.ts +897 -771
- package/src/server/skill-hub/tasks/SkillExecutionTask.ts +15 -0
- package/src/server/tools/agent-loop.ts +399 -0
- package/src/server/tools/delegate-task.ts +23 -485
- package/src/server/tools/orchestrator-plan.ts +279 -0
- package/src/server/tools/skill-execute.ts +68 -64
|
@@ -53,6 +53,7 @@ var import_McpController = require("./mcp/McpController");
|
|
|
53
53
|
var import_SkillRepositoryService = require("../services/SkillRepositoryService");
|
|
54
54
|
var import_git_import = require("./actions/git-import");
|
|
55
55
|
var import_json_fields = require("./utils/json-fields");
|
|
56
|
+
var import_ExecutionSpanService = require("../services/ExecutionSpanService");
|
|
56
57
|
class RateLimiter {
|
|
57
58
|
constructor(maxExecutions = 10, windowMs = 60 * 1e3) {
|
|
58
59
|
this.maxExecutions = maxExecutions;
|
|
@@ -77,9 +78,7 @@ class RateLimiter {
|
|
|
77
78
|
/** Get remaining executions for a user */
|
|
78
79
|
remaining(userId) {
|
|
79
80
|
const now = Date.now();
|
|
80
|
-
const executions = (this.userExecutions.get(userId) || []).filter(
|
|
81
|
-
(t) => now - t < this.windowMs
|
|
82
|
-
);
|
|
81
|
+
const executions = (this.userExecutions.get(userId) || []).filter((t) => now - t < this.windowMs);
|
|
83
82
|
return Math.max(0, this.maxExecutions - executions.length);
|
|
84
83
|
}
|
|
85
84
|
/** Periodically clean up expired entries (call from interval) */
|
|
@@ -152,7 +151,9 @@ class SkillHubSubFeature {
|
|
|
152
151
|
require("fs").rmSync(dir, { recursive: true, force: true });
|
|
153
152
|
}
|
|
154
153
|
} catch (err) {
|
|
155
|
-
this.app.logger.error(`[skill-hub] Failed to cleanup physical storage for execId ${execId}`, {
|
|
154
|
+
this.app.logger.error(`[skill-hub] Failed to cleanup physical storage for execId ${execId}`, {
|
|
155
|
+
error: err
|
|
156
|
+
});
|
|
156
157
|
}
|
|
157
158
|
});
|
|
158
159
|
this.db.on("skillDefinitions.afterSave", async (model, options) => {
|
|
@@ -168,31 +169,56 @@ class SkillHubSubFeature {
|
|
|
168
169
|
this.app.logger.warn("[skill-hub] plugin-file-manager not found, cannot extract skill package");
|
|
169
170
|
return;
|
|
170
171
|
}
|
|
172
|
+
const rawStorageId = attachment.get("storageId") || attachment.storageId;
|
|
173
|
+
if (rawStorageId) {
|
|
174
|
+
const strId = String(rawStorageId);
|
|
175
|
+
let matchedKey = null;
|
|
176
|
+
for (const key of fileManager.storagesCache.keys()) {
|
|
177
|
+
if (String(key) === strId) {
|
|
178
|
+
matchedKey = key;
|
|
179
|
+
break;
|
|
180
|
+
}
|
|
181
|
+
}
|
|
182
|
+
if (matchedKey !== null) {
|
|
183
|
+
attachment.set("storageId", matchedKey);
|
|
184
|
+
attachment.storageId = matchedKey;
|
|
185
|
+
}
|
|
186
|
+
}
|
|
171
187
|
const streamData = await fileManager.getFileStream(attachment);
|
|
172
188
|
if (!streamData || !streamData.stream) {
|
|
173
|
-
this.app.logger.warn(
|
|
189
|
+
this.app.logger.warn(
|
|
190
|
+
`[skill-hub] Could not get file stream for attachment ${attachment.get("id")}`
|
|
191
|
+
);
|
|
174
192
|
return;
|
|
175
193
|
}
|
|
176
194
|
const tempZipPath = (0, import_path.resolve)(os.tmpdir(), `skill_${Date.now()}_${model.get("id")}.zip`);
|
|
177
|
-
await new Promise((
|
|
195
|
+
await new Promise((resolve2, reject) => {
|
|
178
196
|
const writeStream = (0, import_fs.createWriteStream)(tempZipPath);
|
|
179
197
|
streamData.stream.pipe(writeStream);
|
|
180
|
-
writeStream.on("finish",
|
|
181
|
-
writeStream.on("error",
|
|
182
|
-
streamData.stream.on("error",
|
|
198
|
+
writeStream.on("finish", resolve2);
|
|
199
|
+
writeStream.on("error", reject);
|
|
200
|
+
streamData.stream.on("error", reject);
|
|
183
201
|
});
|
|
184
202
|
if (require("fs").existsSync(tempZipPath)) {
|
|
185
203
|
const skillName = model.get("name");
|
|
186
|
-
const { metadata, instructions } = await this.skillRepoService.extractSkillPackage(
|
|
204
|
+
const { metadata, instructions } = await this.skillRepoService.extractSkillPackage(
|
|
205
|
+
skillName,
|
|
206
|
+
tempZipPath
|
|
207
|
+
);
|
|
187
208
|
const code = this.skillRepoService.getSkillCode(skillName);
|
|
188
|
-
const updateValues = {
|
|
209
|
+
const updateValues = {
|
|
210
|
+
storageType: attachment.get("storageId") ? `storage-${attachment.get("storageId")}` : "local"
|
|
211
|
+
};
|
|
189
212
|
if (code) updateValues.codeTemplate = code;
|
|
190
213
|
if (metadata.description) updateValues.description = metadata.description;
|
|
191
214
|
if (metadata.title) updateValues.title = metadata.title;
|
|
192
215
|
if (metadata.language) updateValues.language = metadata.language;
|
|
193
|
-
if (metadata.inputSchema)
|
|
194
|
-
|
|
195
|
-
if (metadata.
|
|
216
|
+
if (metadata.inputSchema)
|
|
217
|
+
updateValues.inputSchema = (0, import_json_fields.stringifyJsonText)((0, import_json_fields.parseJsonLike)(metadata.inputSchema, null));
|
|
218
|
+
if (metadata.interactionSchema)
|
|
219
|
+
updateValues.interactionSchema = (0, import_json_fields.stringifyJsonText)((0, import_json_fields.parseJsonLike)(metadata.interactionSchema, null));
|
|
220
|
+
if (metadata.packages)
|
|
221
|
+
updateValues.packages = (0, import_json_fields.stringifyJsonText)((0, import_json_fields.parseJsonLike)(metadata.packages, []), []);
|
|
196
222
|
if (metadata.timeoutSeconds) updateValues.timeoutSeconds = metadata.timeoutSeconds;
|
|
197
223
|
if (instructions) updateValues.instructions = instructions;
|
|
198
224
|
await this.db.getRepository("skillDefinitions").update({
|
|
@@ -262,12 +288,19 @@ class SkillHubSubFeature {
|
|
|
262
288
|
);
|
|
263
289
|
}
|
|
264
290
|
}
|
|
291
|
+
const traceContext = (0, import_ExecutionSpanService.getOrchestratorTraceContext)(ctx);
|
|
265
292
|
const execution = await this.db.getRepository("skillExecutions").create({
|
|
266
293
|
values: {
|
|
267
294
|
skillId: skill.id,
|
|
268
295
|
status: "pending",
|
|
269
296
|
inputArgs: (0, import_json_fields.stringifyJsonText)(inputArgs, {}),
|
|
270
297
|
sessionId: (_c = ctx == null ? void 0 : ctx.state) == null ? void 0 : _c.sessionId,
|
|
298
|
+
orchestratorRootRunId: traceContext == null ? void 0 : traceContext.rootRunId,
|
|
299
|
+
orchestratorSpanId: traceContext == null ? void 0 : traceContext.spanId,
|
|
300
|
+
orchestratorParentSpanId: traceContext == null ? void 0 : traceContext.parentSpanId,
|
|
301
|
+
orchestratorToolCallId: traceContext == null ? void 0 : traceContext.toolCallId,
|
|
302
|
+
agentLoopRunId: traceContext == null ? void 0 : traceContext.agentLoopRunId,
|
|
303
|
+
agentLoopStepId: traceContext == null ? void 0 : traceContext.agentLoopStepId,
|
|
271
304
|
triggeredById: (_e = (_d = ctx == null ? void 0 : ctx.state) == null ? void 0 : _d.currentUser) == null ? void 0 : _e.id
|
|
272
305
|
}
|
|
273
306
|
});
|
|
@@ -340,7 +373,13 @@ class SkillHubSubFeature {
|
|
|
340
373
|
downloadUrl: `/api/skillHub:download?execId=${execId}&f=${b64name}`
|
|
341
374
|
};
|
|
342
375
|
});
|
|
343
|
-
return {
|
|
376
|
+
return {
|
|
377
|
+
...result,
|
|
378
|
+
files: filesWithUrls,
|
|
379
|
+
execId,
|
|
380
|
+
agentLoopRunId: traceContext == null ? void 0 : traceContext.agentLoopRunId,
|
|
381
|
+
agentLoopStepId: traceContext == null ? void 0 : traceContext.agentLoopStepId
|
|
382
|
+
};
|
|
344
383
|
}
|
|
345
384
|
async handleDownload(ctx, next) {
|
|
346
385
|
var _a, _b;
|
|
@@ -455,6 +494,49 @@ class SkillHubSubFeature {
|
|
|
455
494
|
await this.app.pubSubManager.subscribe("skill-hub.init-env.done", this.initEnvDoneCallback);
|
|
456
495
|
await this.app.pubSubManager.subscribe("skill-hub.init-env.progress", this.initEnvProgressCallback);
|
|
457
496
|
}
|
|
497
|
+
getSkillRecordId(skill) {
|
|
498
|
+
return String(skill.get ? skill.get("id") : skill.id);
|
|
499
|
+
}
|
|
500
|
+
resolveLoopInteractionSchema(loopConfig) {
|
|
501
|
+
if (!loopConfig) return null;
|
|
502
|
+
const schema = (0, import_json_fields.parseJsonText)(loopConfig.get ? loopConfig.get("schema") : loopConfig.schema, null);
|
|
503
|
+
const prompt = loopConfig.get ? loopConfig.get("prompt") : loopConfig.prompt;
|
|
504
|
+
if (schema && typeof schema === "object") {
|
|
505
|
+
return prompt && !schema.prompt ? { ...schema, prompt } : schema;
|
|
506
|
+
}
|
|
507
|
+
if (prompt) {
|
|
508
|
+
return {
|
|
509
|
+
type: "confirm",
|
|
510
|
+
prompt
|
|
511
|
+
};
|
|
512
|
+
}
|
|
513
|
+
return null;
|
|
514
|
+
}
|
|
515
|
+
async getLoopConfigsBySkillId(skillIds) {
|
|
516
|
+
const ids = Array.from(new Set(skillIds.map((id) => String(id)).filter(Boolean)));
|
|
517
|
+
const configsBySkillId = /* @__PURE__ */ new Map();
|
|
518
|
+
if (!ids.length) return configsBySkillId;
|
|
519
|
+
try {
|
|
520
|
+
const configs = await this.db.getRepository("skillLoopConfigs").find({
|
|
521
|
+
filter: {
|
|
522
|
+
enabled: true,
|
|
523
|
+
skillId: {
|
|
524
|
+
$in: ids
|
|
525
|
+
}
|
|
526
|
+
},
|
|
527
|
+
sort: ["-updatedAt"]
|
|
528
|
+
});
|
|
529
|
+
for (const config of configs || []) {
|
|
530
|
+
const skillId = String(config.get ? config.get("skillId") : config.skillId);
|
|
531
|
+
if (!configsBySkillId.has(skillId)) {
|
|
532
|
+
configsBySkillId.set(skillId, config);
|
|
533
|
+
}
|
|
534
|
+
}
|
|
535
|
+
} catch (err) {
|
|
536
|
+
this.app.logger.warn("[skill-hub] Failed to load loop configs", err);
|
|
537
|
+
}
|
|
538
|
+
return configsBySkillId;
|
|
539
|
+
}
|
|
458
540
|
registerAITools() {
|
|
459
541
|
var _a;
|
|
460
542
|
try {
|
|
@@ -470,45 +552,56 @@ class SkillHubSubFeature {
|
|
|
470
552
|
filter: { enabled: true }
|
|
471
553
|
});
|
|
472
554
|
if (!skills || skills.length === 0) return;
|
|
473
|
-
const
|
|
474
|
-
|
|
475
|
-
|
|
476
|
-
|
|
477
|
-
|
|
478
|
-
|
|
479
|
-
|
|
480
|
-
|
|
555
|
+
const loopConfigsBySkillId = await this.getLoopConfigsBySkillId(
|
|
556
|
+
skills.map((skill) => this.getSkillRecordId(skill))
|
|
557
|
+
);
|
|
558
|
+
const tools = await Promise.all(
|
|
559
|
+
skills.map(async (skill) => {
|
|
560
|
+
const sanitizedToolName = skill.get("name").toLowerCase().replace(/[^a-z0-9_]/g, "_").replace(/_+/g, "_").replace(/^_|_$/g, "");
|
|
561
|
+
const autoCall = !!skill.get("autoCall");
|
|
562
|
+
const loopConfig = loopConfigsBySkillId.get(this.getSkillRecordId(skill));
|
|
563
|
+
const loopInteractionSchema = this.resolveLoopInteractionSchema(loopConfig);
|
|
564
|
+
const skillInteractionSchema = (0, import_json_fields.parseJsonText)(skill.get("interactionSchema"), null);
|
|
565
|
+
const interactionSchema = loopInteractionSchema || skillInteractionSchema;
|
|
566
|
+
const requiresHumanReview = !!interactionSchema;
|
|
567
|
+
const fullDescription = await this.getSkillDescriptionForAI(skill);
|
|
568
|
+
const baseDescription = `${fullDescription || skill.get("description")}
|
|
569
|
+
Language: ${skill.get(
|
|
570
|
+
"language"
|
|
571
|
+
)}`;
|
|
572
|
+
const description = requiresHumanReview ? `${baseDescription}
|
|
481
573
|
|
|
482
|
-
IMPORTANT: This skill
|
|
483
|
-
|
|
484
|
-
|
|
485
|
-
|
|
486
|
-
|
|
487
|
-
|
|
488
|
-
|
|
489
|
-
|
|
490
|
-
|
|
491
|
-
|
|
492
|
-
|
|
493
|
-
|
|
494
|
-
|
|
495
|
-
|
|
496
|
-
|
|
497
|
-
|
|
498
|
-
|
|
499
|
-
|
|
500
|
-
|
|
501
|
-
|
|
574
|
+
IMPORTANT: This skill is bound to a Skill Hub human-in-the-loop review template. Pass best-effort args; the user can approve, edit, or reject them before execution.` : baseDescription;
|
|
575
|
+
return {
|
|
576
|
+
scope: "CUSTOM",
|
|
577
|
+
execution: "backend",
|
|
578
|
+
defaultPermission: requiresHumanReview ? "ASK" : autoCall ? "ALLOW" : "ASK",
|
|
579
|
+
introduction: {
|
|
580
|
+
title: `Skill Hub: ${skill.get("title")}`,
|
|
581
|
+
about: skill.get("description") || `Th\u1EF1c thi k\u1EF9 n\u0103ng ${skill.get("title")}`
|
|
582
|
+
},
|
|
583
|
+
definition: {
|
|
584
|
+
name: `skill_hub_${sanitizedToolName}`,
|
|
585
|
+
description,
|
|
586
|
+
schema: (0, import_json_fields.parseJsonText)(skill.get("inputSchema"), { type: "object", properties: {} })
|
|
587
|
+
},
|
|
588
|
+
invoke: async (toolCtx, args) => {
|
|
589
|
+
const latestSkill = await this.db.getRepository("skillDefinitions").findOne({
|
|
590
|
+
filter: { id: skill.get("id"), enabled: true }
|
|
591
|
+
});
|
|
592
|
+
if (!latestSkill) {
|
|
593
|
+
return { status: "error", content: `Skill "${skill.get("name")}" is no longer available` };
|
|
594
|
+
}
|
|
595
|
+
const result = await this.executeSkill(latestSkill, args, toolCtx);
|
|
596
|
+
return {
|
|
597
|
+
status: result.status === "succeeded" ? "success" : "error",
|
|
598
|
+
result
|
|
599
|
+
// Attach raw result
|
|
600
|
+
};
|
|
502
601
|
}
|
|
503
|
-
|
|
504
|
-
|
|
505
|
-
|
|
506
|
-
result
|
|
507
|
-
// Attach raw result
|
|
508
|
-
};
|
|
509
|
-
}
|
|
510
|
-
};
|
|
511
|
-
}));
|
|
602
|
+
};
|
|
603
|
+
})
|
|
604
|
+
);
|
|
512
605
|
register.registerTools(tools);
|
|
513
606
|
} catch (err) {
|
|
514
607
|
this.app.logger.warn("[skill-hub] Failed to provide dynamic tools", err);
|
|
@@ -616,7 +709,9 @@ IMPORTANT: This skill requires human confirmation. Pass best-effort args; the us
|
|
|
616
709
|
*/
|
|
617
710
|
registerSkillTemplate(pluginName, skillDef) {
|
|
618
711
|
this.skillTemplates.set(skillDef.name, this.hydrateSkillTemplate(pluginName, skillDef));
|
|
619
|
-
this.app.logger.info(
|
|
712
|
+
this.app.logger.info(
|
|
713
|
+
`[skill-hub] Registered skill template "${skillDef.name}" from plugin "${pluginName}"`
|
|
714
|
+
);
|
|
620
715
|
}
|
|
621
716
|
resolveSkillTemplate(templateName) {
|
|
622
717
|
if (!templateName) return null;
|
|
@@ -644,7 +739,10 @@ IMPORTANT: This skill requires human confirmation. Pass best-effort args; the us
|
|
|
644
739
|
const description = skill.get ? skill.get("description") : skill.description;
|
|
645
740
|
const instructions = await this.getSkillInstructions(skill);
|
|
646
741
|
const maxInlineInstructionChars = 24e3;
|
|
647
|
-
const inlineInstructions = instructions && instructions.length > maxInlineInstructionChars ? `${instructions.slice(
|
|
742
|
+
const inlineInstructions = instructions && instructions.length > maxInlineInstructionChars ? `${instructions.slice(
|
|
743
|
+
0,
|
|
744
|
+
maxInlineInstructionChars
|
|
745
|
+
)}
|
|
648
746
|
|
|
649
747
|
[Instructions truncated in tool description. Call skill_hub_execute with action="describe" and this skillName to load the complete workflow.]` : instructions;
|
|
650
748
|
return [description, inlineInstructions ? `Instructions:
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import Application from '@nocobase/server';
|
|
2
|
+
import { SandboxRunner } from '../../services/SandboxRunner';
|
|
3
|
+
import { FileManager } from '../../services/FileManager';
|
|
4
|
+
import { SkillRepositoryService } from '../../services/SkillRepositoryService';
|
|
5
|
+
export declare class SkillExecutionTask {
|
|
6
|
+
private execution;
|
|
7
|
+
private sandboxRunner;
|
|
8
|
+
private fileManager;
|
|
9
|
+
private skillRepoService;
|
|
10
|
+
private app;
|
|
11
|
+
constructor(execution: any, sandboxRunner: SandboxRunner, fileManager: FileManager, skillRepoService: SkillRepositoryService, app: Application);
|
|
12
|
+
run(): Promise<void>;
|
|
13
|
+
private renderTemplate;
|
|
14
|
+
private installGeneratedSkillIfRequested;
|
|
15
|
+
private validateGeneratedSkillPackages;
|
|
16
|
+
}
|
|
@@ -163,6 +163,21 @@ class SkillExecutionTask {
|
|
|
163
163
|
const fmPlugin = this.app.pm.get("@nocobase/plugin-file-manager");
|
|
164
164
|
const attachment = await this.app.db.getRepository("attachments").findOne({ filter: { id: fileId } });
|
|
165
165
|
if (fmPlugin && attachment) {
|
|
166
|
+
const rawStorageId = attachment.get("storageId") || attachment.storageId;
|
|
167
|
+
if (rawStorageId) {
|
|
168
|
+
const strId = String(rawStorageId);
|
|
169
|
+
let matchedKey = null;
|
|
170
|
+
for (const key of fmPlugin.storagesCache.keys()) {
|
|
171
|
+
if (String(key) === strId) {
|
|
172
|
+
matchedKey = key;
|
|
173
|
+
break;
|
|
174
|
+
}
|
|
175
|
+
}
|
|
176
|
+
if (matchedKey !== null) {
|
|
177
|
+
attachment.set("storageId", matchedKey);
|
|
178
|
+
attachment.storageId = matchedKey;
|
|
179
|
+
}
|
|
180
|
+
}
|
|
166
181
|
try {
|
|
167
182
|
const streamData = await fmPlugin.getFileStream(attachment);
|
|
168
183
|
if (streamData == null ? void 0 : streamData.stream) {
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
export declare function parseJsonText<T = any>(value: any, fallback: T): T;
|
|
2
|
+
export declare function stringifyJsonText(value: any, fallback?: any): string;
|
|
3
|
+
export declare function parseJsonLike(value: any, fallback: any): any;
|
|
4
|
+
export declare function parseSkillMarkdown(markdown: string): {
|
|
5
|
+
metadata: Record<string, any>;
|
|
6
|
+
body: string;
|
|
7
|
+
};
|
|
@@ -0,0 +1,235 @@
|
|
|
1
|
+
import { z } from 'zod';
|
|
2
|
+
import { AgentLoopService } from '../services/AgentLoopService';
|
|
3
|
+
export declare function createAgentLoopTools(plugin: any, service: AgentLoopService): ({
|
|
4
|
+
scope: "CUSTOM";
|
|
5
|
+
execution: "backend";
|
|
6
|
+
defaultPermission: "ALLOW";
|
|
7
|
+
introduction: {
|
|
8
|
+
title: string;
|
|
9
|
+
about: string;
|
|
10
|
+
};
|
|
11
|
+
definition: {
|
|
12
|
+
name: string;
|
|
13
|
+
description: string;
|
|
14
|
+
schema: z.ZodObject<{
|
|
15
|
+
goal: z.ZodString;
|
|
16
|
+
leaderUsername: z.ZodOptional<z.ZodString>;
|
|
17
|
+
sessionId: z.ZodOptional<z.ZodString>;
|
|
18
|
+
messageId: z.ZodOptional<z.ZodString>;
|
|
19
|
+
policy: z.ZodOptional<z.ZodObject<{
|
|
20
|
+
maxIterations: z.ZodOptional<z.ZodNumber>;
|
|
21
|
+
maxStepAttempts: z.ZodOptional<z.ZodNumber>;
|
|
22
|
+
allowReplan: z.ZodOptional<z.ZodBoolean>;
|
|
23
|
+
requireVerification: z.ZodOptional<z.ZodBoolean>;
|
|
24
|
+
stopOnApprovalRequired: z.ZodOptional<z.ZodBoolean>;
|
|
25
|
+
}, "strip", z.ZodTypeAny, {
|
|
26
|
+
maxIterations?: number;
|
|
27
|
+
maxStepAttempts?: number;
|
|
28
|
+
allowReplan?: boolean;
|
|
29
|
+
requireVerification?: boolean;
|
|
30
|
+
stopOnApprovalRequired?: boolean;
|
|
31
|
+
}, {
|
|
32
|
+
maxIterations?: number;
|
|
33
|
+
maxStepAttempts?: number;
|
|
34
|
+
allowReplan?: boolean;
|
|
35
|
+
requireVerification?: boolean;
|
|
36
|
+
stopOnApprovalRequired?: boolean;
|
|
37
|
+
}>>;
|
|
38
|
+
metadata: z.ZodOptional<z.ZodAny>;
|
|
39
|
+
plan: z.ZodOptional<z.ZodArray<z.ZodObject<{
|
|
40
|
+
id: z.ZodOptional<z.ZodString>;
|
|
41
|
+
key: z.ZodOptional<z.ZodString>;
|
|
42
|
+
planKey: z.ZodOptional<z.ZodString>;
|
|
43
|
+
parentStepId: z.ZodOptional<z.ZodUnion<[z.ZodString, z.ZodNumber]>>;
|
|
44
|
+
title: z.ZodOptional<z.ZodString>;
|
|
45
|
+
description: z.ZodOptional<z.ZodString>;
|
|
46
|
+
type: z.ZodOptional<z.ZodEnum<["reasoning", "skill", "tool", "sub_agent", "verification"]>>;
|
|
47
|
+
target: z.ZodOptional<z.ZodString>;
|
|
48
|
+
input: z.ZodOptional<z.ZodAny>;
|
|
49
|
+
dependsOn: z.ZodOptional<z.ZodArray<z.ZodString, "many">>;
|
|
50
|
+
maxAttempts: z.ZodOptional<z.ZodNumber>;
|
|
51
|
+
metadata: z.ZodOptional<z.ZodAny>;
|
|
52
|
+
}, "strip", z.ZodTypeAny, {
|
|
53
|
+
type?: "reasoning" | "skill" | "tool" | "sub_agent" | "verification";
|
|
54
|
+
key?: string;
|
|
55
|
+
title?: string;
|
|
56
|
+
description?: string;
|
|
57
|
+
metadata?: any;
|
|
58
|
+
input?: any;
|
|
59
|
+
planKey?: string;
|
|
60
|
+
target?: string;
|
|
61
|
+
dependsOn?: string[];
|
|
62
|
+
id?: string;
|
|
63
|
+
parentStepId?: string | number;
|
|
64
|
+
maxAttempts?: number;
|
|
65
|
+
}, {
|
|
66
|
+
type?: "reasoning" | "skill" | "tool" | "sub_agent" | "verification";
|
|
67
|
+
key?: string;
|
|
68
|
+
title?: string;
|
|
69
|
+
description?: string;
|
|
70
|
+
metadata?: any;
|
|
71
|
+
input?: any;
|
|
72
|
+
planKey?: string;
|
|
73
|
+
target?: string;
|
|
74
|
+
dependsOn?: string[];
|
|
75
|
+
id?: string;
|
|
76
|
+
parentStepId?: string | number;
|
|
77
|
+
maxAttempts?: number;
|
|
78
|
+
}>, "many">>;
|
|
79
|
+
}, "strip", z.ZodTypeAny, {
|
|
80
|
+
leaderUsername?: string;
|
|
81
|
+
metadata?: any;
|
|
82
|
+
sessionId?: string;
|
|
83
|
+
goal?: string;
|
|
84
|
+
messageId?: string;
|
|
85
|
+
policy?: {
|
|
86
|
+
maxIterations?: number;
|
|
87
|
+
maxStepAttempts?: number;
|
|
88
|
+
allowReplan?: boolean;
|
|
89
|
+
requireVerification?: boolean;
|
|
90
|
+
stopOnApprovalRequired?: boolean;
|
|
91
|
+
};
|
|
92
|
+
plan?: {
|
|
93
|
+
type?: "reasoning" | "skill" | "tool" | "sub_agent" | "verification";
|
|
94
|
+
key?: string;
|
|
95
|
+
title?: string;
|
|
96
|
+
description?: string;
|
|
97
|
+
metadata?: any;
|
|
98
|
+
input?: any;
|
|
99
|
+
planKey?: string;
|
|
100
|
+
target?: string;
|
|
101
|
+
dependsOn?: string[];
|
|
102
|
+
id?: string;
|
|
103
|
+
parentStepId?: string | number;
|
|
104
|
+
maxAttempts?: number;
|
|
105
|
+
}[];
|
|
106
|
+
}, {
|
|
107
|
+
leaderUsername?: string;
|
|
108
|
+
metadata?: any;
|
|
109
|
+
sessionId?: string;
|
|
110
|
+
goal?: string;
|
|
111
|
+
messageId?: string;
|
|
112
|
+
policy?: {
|
|
113
|
+
maxIterations?: number;
|
|
114
|
+
maxStepAttempts?: number;
|
|
115
|
+
allowReplan?: boolean;
|
|
116
|
+
requireVerification?: boolean;
|
|
117
|
+
stopOnApprovalRequired?: boolean;
|
|
118
|
+
};
|
|
119
|
+
plan?: {
|
|
120
|
+
type?: "reasoning" | "skill" | "tool" | "sub_agent" | "verification";
|
|
121
|
+
key?: string;
|
|
122
|
+
title?: string;
|
|
123
|
+
description?: string;
|
|
124
|
+
metadata?: any;
|
|
125
|
+
input?: any;
|
|
126
|
+
planKey?: string;
|
|
127
|
+
target?: string;
|
|
128
|
+
dependsOn?: string[];
|
|
129
|
+
id?: string;
|
|
130
|
+
parentStepId?: string | number;
|
|
131
|
+
maxAttempts?: number;
|
|
132
|
+
}[];
|
|
133
|
+
}>;
|
|
134
|
+
};
|
|
135
|
+
invoke: (ctx: any, args: any) => Promise<{
|
|
136
|
+
status: "success" | "error";
|
|
137
|
+
content: string;
|
|
138
|
+
}>;
|
|
139
|
+
} | {
|
|
140
|
+
scope: "CUSTOM";
|
|
141
|
+
execution: "backend";
|
|
142
|
+
defaultPermission: "ALLOW";
|
|
143
|
+
introduction: {
|
|
144
|
+
title: string;
|
|
145
|
+
about: string;
|
|
146
|
+
};
|
|
147
|
+
definition: {
|
|
148
|
+
name: string;
|
|
149
|
+
description: string;
|
|
150
|
+
schema: z.ZodObject<{
|
|
151
|
+
runId: z.ZodUnion<[z.ZodString, z.ZodNumber]>;
|
|
152
|
+
}, "strip", z.ZodTypeAny, {
|
|
153
|
+
runId?: string | number;
|
|
154
|
+
}, {
|
|
155
|
+
runId?: string | number;
|
|
156
|
+
}>;
|
|
157
|
+
};
|
|
158
|
+
invoke: (ctx: any, args: any) => Promise<{
|
|
159
|
+
status: "success" | "error";
|
|
160
|
+
content: string;
|
|
161
|
+
}>;
|
|
162
|
+
} | {
|
|
163
|
+
scope: "CUSTOM";
|
|
164
|
+
execution: "backend";
|
|
165
|
+
defaultPermission: "ALLOW";
|
|
166
|
+
introduction: {
|
|
167
|
+
title: string;
|
|
168
|
+
about: string;
|
|
169
|
+
};
|
|
170
|
+
definition: {
|
|
171
|
+
name: string;
|
|
172
|
+
description: string;
|
|
173
|
+
schema: z.ZodObject<{
|
|
174
|
+
stepId: z.ZodUnion<[z.ZodString, z.ZodNumber]>;
|
|
175
|
+
status: z.ZodEnum<["running", "succeeded", "failed", "skipped"]>;
|
|
176
|
+
output: z.ZodOptional<z.ZodAny>;
|
|
177
|
+
error: z.ZodOptional<z.ZodString>;
|
|
178
|
+
reason: z.ZodOptional<z.ZodString>;
|
|
179
|
+
skillExecutionId: z.ZodOptional<z.ZodUnion<[z.ZodString, z.ZodNumber]>>;
|
|
180
|
+
agentExecutionSpanId: z.ZodOptional<z.ZodUnion<[z.ZodString, z.ZodNumber]>>;
|
|
181
|
+
metadata: z.ZodOptional<z.ZodAny>;
|
|
182
|
+
}, "strip", z.ZodTypeAny, {
|
|
183
|
+
error?: string;
|
|
184
|
+
status?: "running" | "succeeded" | "failed" | "skipped";
|
|
185
|
+
metadata?: any;
|
|
186
|
+
output?: any;
|
|
187
|
+
skillExecutionId?: string | number;
|
|
188
|
+
reason?: string;
|
|
189
|
+
stepId?: string | number;
|
|
190
|
+
agentExecutionSpanId?: string | number;
|
|
191
|
+
}, {
|
|
192
|
+
error?: string;
|
|
193
|
+
status?: "running" | "succeeded" | "failed" | "skipped";
|
|
194
|
+
metadata?: any;
|
|
195
|
+
output?: any;
|
|
196
|
+
skillExecutionId?: string | number;
|
|
197
|
+
reason?: string;
|
|
198
|
+
stepId?: string | number;
|
|
199
|
+
agentExecutionSpanId?: string | number;
|
|
200
|
+
}>;
|
|
201
|
+
};
|
|
202
|
+
invoke: (ctx: any, args: any) => Promise<{
|
|
203
|
+
status: "success" | "error";
|
|
204
|
+
content: string;
|
|
205
|
+
}>;
|
|
206
|
+
} | {
|
|
207
|
+
scope: "CUSTOM";
|
|
208
|
+
execution: "backend";
|
|
209
|
+
defaultPermission: "ALLOW";
|
|
210
|
+
introduction: {
|
|
211
|
+
title: string;
|
|
212
|
+
about: string;
|
|
213
|
+
};
|
|
214
|
+
definition: {
|
|
215
|
+
name: string;
|
|
216
|
+
description: string;
|
|
217
|
+
schema: z.ZodObject<{
|
|
218
|
+
stepId: z.ZodUnion<[z.ZodString, z.ZodNumber]>;
|
|
219
|
+
reason: z.ZodOptional<z.ZodString>;
|
|
220
|
+
approval: z.ZodOptional<z.ZodAny>;
|
|
221
|
+
}, "strip", z.ZodTypeAny, {
|
|
222
|
+
reason?: string;
|
|
223
|
+
stepId?: string | number;
|
|
224
|
+
approval?: any;
|
|
225
|
+
}, {
|
|
226
|
+
reason?: string;
|
|
227
|
+
stepId?: string | number;
|
|
228
|
+
approval?: any;
|
|
229
|
+
}>;
|
|
230
|
+
};
|
|
231
|
+
invoke: (ctx: any, args: any) => Promise<{
|
|
232
|
+
status: "success" | "error";
|
|
233
|
+
content: string;
|
|
234
|
+
}>;
|
|
235
|
+
})[];
|