@crewx/cli 0.8.3-rc.9 → 0.8.4-rc.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/README.md +33 -33
- package/bin/crewx +2 -2
- package/dist/ai-provider.service.d.ts +34 -0
- package/dist/ai-provider.service.js +311 -0
- package/dist/ai-provider.service.js.map +1 -0
- package/dist/ai.service.d.ts +17 -0
- package/dist/ai.service.js +51 -0
- package/dist/ai.service.js.map +1 -0
- package/dist/app.module.d.ts +5 -0
- package/dist/app.module.js +165 -0
- package/dist/app.module.js.map +1 -0
- package/dist/cli/agent.handler.d.ts +2 -0
- package/dist/cli/agent.handler.js +186 -0
- package/dist/cli/agent.handler.js.map +1 -0
- package/dist/cli/builtin.handler.d.ts +3 -0
- package/dist/cli/builtin.handler.js +110 -0
- package/dist/cli/builtin.handler.js.map +1 -0
- package/dist/cli/chat.handler.d.ts +20 -0
- package/dist/cli/chat.handler.js +446 -0
- package/dist/cli/chat.handler.js.map +1 -0
- package/dist/cli/cli.handler.d.ts +4 -0
- package/dist/cli/cli.handler.js +119 -0
- package/dist/cli/cli.handler.js.map +1 -0
- package/dist/cli/doctor.handler.d.ts +38 -0
- package/dist/cli/doctor.handler.js +495 -0
- package/dist/cli/doctor.handler.js.map +1 -0
- package/dist/cli/execute.handler.d.ts +2 -0
- package/dist/cli/execute.handler.js +321 -0
- package/dist/cli/execute.handler.js.map +1 -0
- package/dist/cli/help.handler.d.ts +2 -0
- package/dist/cli/help.handler.js +10 -0
- package/dist/cli/help.handler.js.map +1 -0
- package/dist/cli/init.handler.d.ts +26 -0
- package/dist/cli/init.handler.js +450 -0
- package/dist/cli/init.handler.js.map +1 -0
- package/dist/cli/log.handler.d.ts +2 -0
- package/dist/cli/log.handler.js +69 -0
- package/dist/cli/log.handler.js.map +1 -0
- package/dist/cli/mcp.handler.d.ts +3 -0
- package/dist/cli/mcp.handler.js +121 -0
- package/dist/cli/mcp.handler.js.map +1 -0
- package/dist/cli/query.handler.d.ts +2 -0
- package/dist/cli/query.handler.js +379 -0
- package/dist/cli/query.handler.js.map +1 -0
- package/dist/cli/skill.handler.d.ts +2 -0
- package/dist/cli/skill.handler.js +252 -0
- package/dist/cli/skill.handler.js.map +1 -0
- package/dist/cli/slack-files.handler.d.ts +2 -0
- package/dist/cli/slack-files.handler.js +291 -0
- package/dist/cli/slack-files.handler.js.map +1 -0
- package/dist/cli/template.handler.d.ts +2 -0
- package/dist/cli/template.handler.js +188 -0
- package/dist/cli/template.handler.js.map +1 -0
- package/dist/cli/templates.handler.d.ts +2 -0
- package/dist/cli/templates.handler.js +100 -0
- package/dist/cli/templates.handler.js.map +1 -0
- package/dist/cli-options.d.ts +39 -0
- package/dist/cli-options.js +355 -0
- package/dist/cli-options.js.map +1 -0
- package/dist/commands/agent.js +23 -23
- package/dist/commands/init.js +36 -28
- package/dist/commands/resolve-prompt.d.ts +4 -4
- package/dist/commands/resolve-prompt.js +5 -5
- package/dist/config/timeout.config.d.ts +14 -0
- package/dist/config/timeout.config.js +34 -0
- package/dist/config/timeout.config.js.map +1 -0
- package/dist/conversation/base-conversation-history.provider.d.ts +12 -0
- package/dist/conversation/base-conversation-history.provider.js +45 -0
- package/dist/conversation/base-conversation-history.provider.js.map +1 -0
- package/dist/conversation/cli-conversation-history.provider.d.ts +16 -0
- package/dist/conversation/cli-conversation-history.provider.js +111 -0
- package/dist/conversation/cli-conversation-history.provider.js.map +1 -0
- package/dist/conversation/conversation-provider.factory.d.ts +10 -0
- package/dist/conversation/conversation-provider.factory.js +50 -0
- package/dist/conversation/conversation-provider.factory.js.map +1 -0
- package/dist/conversation/index.d.ts +6 -0
- package/dist/conversation/index.js +27 -0
- package/dist/conversation/index.js.map +1 -0
- package/dist/conversation/slack-conversation-history.provider.d.ts +29 -0
- package/dist/conversation/slack-conversation-history.provider.js +302 -0
- package/dist/conversation/slack-conversation-history.provider.js.map +1 -0
- package/dist/crewx.tool.d.ts +359 -0
- package/dist/crewx.tool.js +2501 -0
- package/dist/crewx.tool.js.map +1 -0
- package/dist/crewx.tool.spec.d.ts +1 -0
- package/dist/crewx.tool.spec.js +158 -0
- package/dist/crewx.tool.spec.js.map +1 -0
- package/dist/guards/bearer-auth.guard.d.ts +7 -0
- package/dist/guards/bearer-auth.guard.js +44 -0
- package/dist/guards/bearer-auth.guard.js.map +1 -0
- package/dist/health.controller.d.ts +6 -0
- package/dist/health.controller.js +32 -0
- package/dist/health.controller.js.map +1 -0
- package/dist/main.js +72 -71
- package/dist/main.js.map +1 -0
- package/dist/mcp.controller.d.ts +8 -0
- package/dist/mcp.controller.js +62 -0
- package/dist/mcp.controller.js.map +1 -0
- package/dist/package.json +3 -0
- package/dist/providers/dynamic-provider.factory.d.ts +15 -0
- package/dist/providers/dynamic-provider.factory.js +133 -0
- package/dist/providers/dynamic-provider.factory.js.map +1 -0
- package/dist/providers/logger.adapter.d.ts +6 -0
- package/dist/providers/logger.adapter.js +102 -0
- package/dist/providers/logger.adapter.js.map +1 -0
- package/dist/services/agent-loader.service.d.ts +35 -0
- package/dist/services/agent-loader.service.js +622 -0
- package/dist/services/agent-loader.service.js.map +1 -0
- package/dist/services/auth.service.d.ts +9 -0
- package/dist/services/auth.service.js +47 -0
- package/dist/services/auth.service.js.map +1 -0
- package/dist/services/config-validator.service.d.ts +29 -0
- package/dist/services/config-validator.service.js +483 -0
- package/dist/services/config-validator.service.js.map +1 -0
- package/dist/services/config.service.d.ts +45 -0
- package/dist/services/config.service.js +352 -0
- package/dist/services/config.service.js.map +1 -0
- package/dist/services/document-loader.service.d.ts +21 -0
- package/dist/services/document-loader.service.js +156 -0
- package/dist/services/document-loader.service.js.map +1 -0
- package/dist/services/help.service.d.ts +5 -0
- package/dist/services/help.service.js +139 -0
- package/dist/services/help.service.js.map +1 -0
- package/dist/services/intelligent-compression.service.d.ts +20 -0
- package/dist/services/intelligent-compression.service.js +179 -0
- package/dist/services/intelligent-compression.service.js.map +1 -0
- package/dist/services/mcp-client.service.d.ts +26 -0
- package/dist/services/mcp-client.service.js +81 -0
- package/dist/services/mcp-client.service.js.map +1 -0
- package/dist/services/parallel-processing.service.d.ts +108 -0
- package/dist/services/parallel-processing.service.js +333 -0
- package/dist/services/parallel-processing.service.js.map +1 -0
- package/dist/services/provider-bridge.service.d.ts +35 -0
- package/dist/services/provider-bridge.service.js +224 -0
- package/dist/services/provider-bridge.service.js.map +1 -0
- package/dist/services/remote-agent.service.d.ts +50 -0
- package/dist/services/remote-agent.service.js +171 -0
- package/dist/services/remote-agent.service.js.map +1 -0
- package/dist/services/result-formatter.service.d.ts +27 -0
- package/dist/services/result-formatter.service.js +126 -0
- package/dist/services/result-formatter.service.js.map +1 -0
- package/dist/services/skill-loader.service.d.ts +15 -0
- package/dist/services/skill-loader.service.js +278 -0
- package/dist/services/skill-loader.service.js.map +1 -0
- package/dist/services/skill.service.d.ts +67 -0
- package/dist/services/skill.service.js +670 -0
- package/dist/services/skill.service.js.map +1 -0
- package/dist/services/skill.service.spec.d.ts +1 -0
- package/dist/services/skill.service.spec.js +35 -0
- package/dist/services/skill.service.spec.js.map +1 -0
- package/dist/services/task-management.service.d.ts +65 -0
- package/dist/services/task-management.service.js +288 -0
- package/dist/services/task-management.service.js.map +1 -0
- package/dist/services/template.service.d.ts +61 -0
- package/dist/services/template.service.js +416 -0
- package/dist/services/template.service.js.map +1 -0
- package/dist/services/tool-call.service.d.ts +19 -0
- package/dist/services/tool-call.service.js +1061 -0
- package/dist/services/tool-call.service.js.map +1 -0
- package/dist/services/tracing.service.d.ts +200 -0
- package/dist/services/tracing.service.js +1290 -0
- package/dist/services/tracing.service.js.map +1 -0
- package/dist/slack/formatters/message.formatter.d.ts +32 -0
- package/dist/slack/formatters/message.formatter.js +352 -0
- package/dist/slack/formatters/message.formatter.js.map +1 -0
- package/dist/slack/services/slack-file-download.service.d.ts +58 -0
- package/dist/slack/services/slack-file-download.service.js +558 -0
- package/dist/slack/services/slack-file-download.service.js.map +1 -0
- package/dist/slack/slack-bot.d.ts +33 -0
- package/dist/slack/slack-bot.js +567 -0
- package/dist/slack/slack-bot.js.map +1 -0
- package/dist/stderr.logger.d.ts +8 -0
- package/dist/stderr.logger.js +26 -0
- package/dist/stderr.logger.js.map +1 -0
- package/dist/types/usage.types.d.ts +107 -0
- package/dist/types/usage.types.js +3 -0
- package/dist/types/usage.types.js.map +1 -0
- package/dist/utils/config-utils.d.ts +15 -0
- package/dist/utils/config-utils.js +69 -0
- package/dist/utils/config-utils.js.map +1 -0
- package/dist/utils/extract-text.d.ts +1 -0
- package/dist/utils/extract-text.js +15 -0
- package/dist/utils/extract-text.js.map +1 -0
- package/dist/utils/mcp-installer.d.ts +20 -0
- package/dist/utils/mcp-installer.js +199 -0
- package/dist/utils/mcp-installer.js.map +1 -0
- package/dist/utils/project-hash.d.ts +6 -0
- package/dist/utils/project-hash.js +70 -0
- package/dist/utils/project-hash.js.map +1 -0
- package/dist/utils/simple-security.d.ts +3 -0
- package/dist/utils/simple-security.js +20 -0
- package/dist/utils/simple-security.js.map +1 -0
- package/dist/utils/stdin-utils.d.ts +6 -0
- package/dist/utils/stdin-utils.js +109 -0
- package/dist/utils/stdin-utils.js.map +1 -0
- package/dist/utils/template-processor.d.ts +4 -0
- package/dist/utils/template-processor.js +266 -0
- package/dist/utils/template-processor.js.map +1 -0
- package/dist/utils/terminal-message-formatter.d.ts +23 -0
- package/dist/utils/terminal-message-formatter.js +136 -0
- package/dist/utils/terminal-message-formatter.js.map +1 -0
- package/dist/version.d.ts +1 -0
- package/dist/version.js +17 -0
- package/dist/version.js.map +1 -0
- package/dist/workspace.service.d.ts +44 -0
- package/dist/workspace.service.js +299 -0
- package/dist/workspace.service.js.map +1 -0
- package/package.json +18 -18
- package/dist/commands/task-db.d.ts +0 -33
- package/dist/commands/task-db.js +0 -107
- package/dist/examples/deny-secrets-plugin.d.ts +0 -22
- package/dist/examples/deny-secrets-plugin.js +0 -40
- package/dist/plugins/examples/echo-hook.d.ts +0 -24
- package/dist/plugins/examples/echo-hook.js +0 -60
- package/dist/plugins/examples/verify-echo-hook.d.ts +0 -8
- package/dist/plugins/examples/verify-echo-hook.js +0 -47
- package/dist/plugins/sqlite-tracing.d.ts +0 -11
- package/dist/plugins/sqlite-tracing.js +0 -19
- package/dist/repository/workspace.repository.d.ts +0 -26
- package/dist/repository/workspace.repository.js +0 -111
- package/dist/schema/tasks.d.ts +0 -7
- package/dist/schema/tasks.js +0 -48
|
@@ -0,0 +1,2501 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
3
|
+
if (k2 === undefined) k2 = k;
|
|
4
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
5
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
6
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
7
|
+
}
|
|
8
|
+
Object.defineProperty(o, k2, desc);
|
|
9
|
+
}) : (function(o, m, k, k2) {
|
|
10
|
+
if (k2 === undefined) k2 = k;
|
|
11
|
+
o[k2] = m[k];
|
|
12
|
+
}));
|
|
13
|
+
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
14
|
+
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
15
|
+
}) : function(o, v) {
|
|
16
|
+
o["default"] = v;
|
|
17
|
+
});
|
|
18
|
+
var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
|
|
19
|
+
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
|
|
20
|
+
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
|
|
21
|
+
else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
|
|
22
|
+
return c > 3 && r && Object.defineProperty(target, key, r), r;
|
|
23
|
+
};
|
|
24
|
+
var __importStar = (this && this.__importStar) || (function () {
|
|
25
|
+
var ownKeys = function(o) {
|
|
26
|
+
ownKeys = Object.getOwnPropertyNames || function (o) {
|
|
27
|
+
var ar = [];
|
|
28
|
+
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
|
|
29
|
+
return ar;
|
|
30
|
+
};
|
|
31
|
+
return ownKeys(o);
|
|
32
|
+
};
|
|
33
|
+
return function (mod) {
|
|
34
|
+
if (mod && mod.__esModule) return mod;
|
|
35
|
+
var result = {};
|
|
36
|
+
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
|
|
37
|
+
__setModuleDefault(result, mod);
|
|
38
|
+
return result;
|
|
39
|
+
};
|
|
40
|
+
})();
|
|
41
|
+
var __metadata = (this && this.__metadata) || function (k, v) {
|
|
42
|
+
if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
|
|
43
|
+
};
|
|
44
|
+
var __param = (this && this.__param) || function (paramIndex, decorator) {
|
|
45
|
+
return function (target, key) { decorator(target, key, paramIndex); }
|
|
46
|
+
};
|
|
47
|
+
var CrewXTool_1;
|
|
48
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
49
|
+
exports.CrewXTool = void 0;
|
|
50
|
+
const crewx_sdk_1 = require("@sowonai/crewx-sdk");
|
|
51
|
+
const common_1 = require("@nestjs/common");
|
|
52
|
+
const nestjs_mcp_adapter_1 = require("@sowonai/nestjs-mcp-adapter");
|
|
53
|
+
const zod_1 = require("zod");
|
|
54
|
+
const fs = __importStar(require("fs"));
|
|
55
|
+
const path = __importStar(require("path"));
|
|
56
|
+
const crypto = __importStar(require("crypto"));
|
|
57
|
+
const ai_service_1 = require("./ai.service");
|
|
58
|
+
const ai_provider_service_1 = require("./ai-provider.service");
|
|
59
|
+
const workspace_service_1 = require("./workspace.service");
|
|
60
|
+
const parallel_processing_service_1 = require("./services/parallel-processing.service");
|
|
61
|
+
const task_management_service_1 = require("./services/task-management.service");
|
|
62
|
+
const result_formatter_service_1 = require("./services/result-formatter.service");
|
|
63
|
+
const template_service_1 = require("./services/template.service");
|
|
64
|
+
const document_loader_service_1 = require("./services/document-loader.service");
|
|
65
|
+
const tool_call_service_1 = require("./services/tool-call.service");
|
|
66
|
+
const agent_loader_service_1 = require("./services/agent-loader.service");
|
|
67
|
+
const remote_agent_service_1 = require("./services/remote-agent.service");
|
|
68
|
+
const provider_bridge_service_1 = require("./services/provider-bridge.service");
|
|
69
|
+
const skill_loader_service_1 = require("./services/skill-loader.service");
|
|
70
|
+
const tracing_service_1 = require("./services/tracing.service");
|
|
71
|
+
const version_1 = require("./version");
|
|
72
|
+
const extract_text_1 = require("./utils/extract-text");
|
|
73
|
+
let CrewXTool = CrewXTool_1 = class CrewXTool {
|
|
74
|
+
generateSecurityKey() {
|
|
75
|
+
return crypto.randomBytes(8).toString('hex');
|
|
76
|
+
}
|
|
77
|
+
async processAgentEnv(env, agent) {
|
|
78
|
+
if (!env || Object.keys(env).length === 0) {
|
|
79
|
+
return undefined;
|
|
80
|
+
}
|
|
81
|
+
const Handlebars = await Promise.resolve().then(() => __importStar(require('handlebars')));
|
|
82
|
+
const processedEnv = {};
|
|
83
|
+
const context = {
|
|
84
|
+
agent: {
|
|
85
|
+
id: agent.id,
|
|
86
|
+
name: agent.name || agent.id,
|
|
87
|
+
role: agent.role || '',
|
|
88
|
+
team: agent.team || '',
|
|
89
|
+
description: agent.description || '',
|
|
90
|
+
workingDirectory: agent.workingDirectory,
|
|
91
|
+
provider: Array.isArray(agent.provider) ? agent.provider[0] : agent.provider,
|
|
92
|
+
model: agent.inline?.model || '',
|
|
93
|
+
},
|
|
94
|
+
env: process.env,
|
|
95
|
+
};
|
|
96
|
+
for (const [key, value] of Object.entries(env)) {
|
|
97
|
+
try {
|
|
98
|
+
if (value.includes('{{')) {
|
|
99
|
+
const template = Handlebars.compile(value);
|
|
100
|
+
processedEnv[key] = template(context);
|
|
101
|
+
}
|
|
102
|
+
else {
|
|
103
|
+
processedEnv[key] = value;
|
|
104
|
+
}
|
|
105
|
+
}
|
|
106
|
+
catch (error) {
|
|
107
|
+
this.logger.warn(`Failed to process env template for ${key}: ${(0, crewx_sdk_1.getErrorMessage)(error)}`);
|
|
108
|
+
processedEnv[key] = value;
|
|
109
|
+
}
|
|
110
|
+
}
|
|
111
|
+
return processedEnv;
|
|
112
|
+
}
|
|
113
|
+
buildToolsContext() {
|
|
114
|
+
const tools = this.toolCallService.list();
|
|
115
|
+
if (!tools || tools.length === 0) {
|
|
116
|
+
return undefined;
|
|
117
|
+
}
|
|
118
|
+
return {
|
|
119
|
+
list: tools.map(t => ({
|
|
120
|
+
name: t.name,
|
|
121
|
+
description: t.description,
|
|
122
|
+
input_schema: t.input_schema,
|
|
123
|
+
output_schema: t.output_schema,
|
|
124
|
+
})),
|
|
125
|
+
json: JSON.stringify(tools, null, 2),
|
|
126
|
+
count: tools.length,
|
|
127
|
+
};
|
|
128
|
+
}
|
|
129
|
+
async buildStructuredPayload(params) {
|
|
130
|
+
const { agentId, provider, mode, prompt, context, messages, platform, model, platformMetadata } = params;
|
|
131
|
+
const safeMessages = Array.isArray(messages) ? messages : [];
|
|
132
|
+
let formattedHistory = '';
|
|
133
|
+
try {
|
|
134
|
+
if (safeMessages.length > 0) {
|
|
135
|
+
const template = '{{{formatConversation messages platform}}}';
|
|
136
|
+
const { processDocumentTemplate } = await Promise.resolve().then(() => __importStar(require('./utils/template-processor')));
|
|
137
|
+
formattedHistory = await processDocumentTemplate(template, this.documentLoaderService, {
|
|
138
|
+
messages: safeMessages,
|
|
139
|
+
platform: platform ?? 'cli',
|
|
140
|
+
});
|
|
141
|
+
formattedHistory = formattedHistory?.trim() ?? '';
|
|
142
|
+
}
|
|
143
|
+
}
|
|
144
|
+
catch (error) {
|
|
145
|
+
this.logger.warn(`Failed to format conversation history for structured payload: ${error?.message || error}`);
|
|
146
|
+
}
|
|
147
|
+
const normalizedContext = context?.trim() ?? '';
|
|
148
|
+
const payload = {
|
|
149
|
+
version: '1.0',
|
|
150
|
+
agent: {
|
|
151
|
+
id: agentId,
|
|
152
|
+
provider,
|
|
153
|
+
mode,
|
|
154
|
+
model: model || null,
|
|
155
|
+
},
|
|
156
|
+
prompt,
|
|
157
|
+
context: normalizedContext,
|
|
158
|
+
messages: safeMessages,
|
|
159
|
+
metadata: {
|
|
160
|
+
platform: platform ?? 'cli',
|
|
161
|
+
formattedHistory,
|
|
162
|
+
messageCount: safeMessages.length,
|
|
163
|
+
generatedAt: new Date().toISOString(),
|
|
164
|
+
originalContext: normalizedContext,
|
|
165
|
+
...platformMetadata,
|
|
166
|
+
},
|
|
167
|
+
};
|
|
168
|
+
return JSON.stringify(payload);
|
|
169
|
+
}
|
|
170
|
+
constructor(aiService, aiProviderService, workspaceService, parallelProcessingService, taskManagementService, resultFormatterService, templateService, documentLoaderService, toolCallService, agentLoaderService, remoteAgentService, providerBridgeService, skillLoaderService, layoutLoader, layoutRenderer, tracingService) {
|
|
171
|
+
this.aiService = aiService;
|
|
172
|
+
this.aiProviderService = aiProviderService;
|
|
173
|
+
this.workspaceService = workspaceService;
|
|
174
|
+
this.parallelProcessingService = parallelProcessingService;
|
|
175
|
+
this.taskManagementService = taskManagementService;
|
|
176
|
+
this.resultFormatterService = resultFormatterService;
|
|
177
|
+
this.templateService = templateService;
|
|
178
|
+
this.documentLoaderService = documentLoaderService;
|
|
179
|
+
this.toolCallService = toolCallService;
|
|
180
|
+
this.agentLoaderService = agentLoaderService;
|
|
181
|
+
this.remoteAgentService = remoteAgentService;
|
|
182
|
+
this.providerBridgeService = providerBridgeService;
|
|
183
|
+
this.skillLoaderService = skillLoaderService;
|
|
184
|
+
this.layoutLoader = layoutLoader;
|
|
185
|
+
this.layoutRenderer = layoutRenderer;
|
|
186
|
+
this.tracingService = tracingService;
|
|
187
|
+
this.logger = new common_1.Logger(CrewXTool_1.name);
|
|
188
|
+
this.timeoutConfig = (0, crewx_sdk_1.getTimeoutConfig)();
|
|
189
|
+
}
|
|
190
|
+
onModuleInit() {
|
|
191
|
+
this.toolCallService.setCrewXTool(this);
|
|
192
|
+
this.logger.log('CrewXTool registered to ToolCallService');
|
|
193
|
+
}
|
|
194
|
+
async getRenderedAgentPrompt(agentId, mockInput) {
|
|
195
|
+
const agents = await this.agentLoaderService.getAllAgents();
|
|
196
|
+
const agent = agents.find((a) => a.id === agentId);
|
|
197
|
+
if (!agent) {
|
|
198
|
+
throw new Error(`Agent '${agentId}' not found.`);
|
|
199
|
+
}
|
|
200
|
+
const securityKey = this.generateSecurityKey();
|
|
201
|
+
const documents = {};
|
|
202
|
+
if (this.documentLoaderService.isInitialized()) {
|
|
203
|
+
const docNames = this.documentLoaderService.getDocumentNames();
|
|
204
|
+
for (const docName of docNames) {
|
|
205
|
+
const content = await this.documentLoaderService.getDocumentContent(docName);
|
|
206
|
+
const toc = await this.documentLoaderService.getDocumentToc(docName);
|
|
207
|
+
const summary = await this.documentLoaderService.getDocumentSummary(docName);
|
|
208
|
+
documents[docName] = {
|
|
209
|
+
content: content || '',
|
|
210
|
+
toc: toc || '',
|
|
211
|
+
summary: summary || '',
|
|
212
|
+
};
|
|
213
|
+
}
|
|
214
|
+
}
|
|
215
|
+
const templateContext = {
|
|
216
|
+
user_input: mockInput || 'Sample input for prompt preview',
|
|
217
|
+
messages: [],
|
|
218
|
+
agent: {
|
|
219
|
+
id: agent.id,
|
|
220
|
+
name: agent.name || agent.id,
|
|
221
|
+
provider: (Array.isArray(agent.provider) ? agent.provider[0] : agent.provider) || 'claude',
|
|
222
|
+
model: agent.inline?.model,
|
|
223
|
+
workingDirectory: agent.workingDirectory || './',
|
|
224
|
+
inline: {
|
|
225
|
+
prompt: agent.inline?.prompt || agent.inline?.system_prompt || agent.systemPrompt || '',
|
|
226
|
+
},
|
|
227
|
+
specialties: agent.specialties,
|
|
228
|
+
capabilities: agent.capabilities,
|
|
229
|
+
description: agent.description,
|
|
230
|
+
},
|
|
231
|
+
documents: documents,
|
|
232
|
+
vars: {
|
|
233
|
+
security_key: securityKey,
|
|
234
|
+
},
|
|
235
|
+
props: {},
|
|
236
|
+
mode: 'query',
|
|
237
|
+
platform: 'cli',
|
|
238
|
+
env: process.env,
|
|
239
|
+
tools: this.buildToolsContext(),
|
|
240
|
+
};
|
|
241
|
+
return this.processAgentSystemPrompt(agent, templateContext);
|
|
242
|
+
}
|
|
243
|
+
async processAgentSystemPrompt(agent, templateContext) {
|
|
244
|
+
const inlineLayout = agent.inline?.layout;
|
|
245
|
+
const baseSystemPrompt = agent.inline?.prompt ||
|
|
246
|
+
agent.inline?.system_prompt ||
|
|
247
|
+
agent.systemPrompt ||
|
|
248
|
+
agent.description ||
|
|
249
|
+
`You are an expert ${agent.id}.`;
|
|
250
|
+
const documentsForTemplate = {};
|
|
251
|
+
if (this.documentLoaderService.isInitialized()) {
|
|
252
|
+
const docNames = this.documentLoaderService.getDocumentNames();
|
|
253
|
+
for (const docName of docNames) {
|
|
254
|
+
const content = await this.documentLoaderService.getDocumentContent(docName);
|
|
255
|
+
const toc = await this.documentLoaderService.getDocumentToc(docName);
|
|
256
|
+
const summary = await this.documentLoaderService.getDocumentSummary(docName);
|
|
257
|
+
documentsForTemplate[docName] = {
|
|
258
|
+
content: content || '',
|
|
259
|
+
toc: toc || '',
|
|
260
|
+
summary: summary || '',
|
|
261
|
+
};
|
|
262
|
+
}
|
|
263
|
+
}
|
|
264
|
+
const layoutSpec = inlineLayout ?? 'crewx/default';
|
|
265
|
+
if (layoutSpec) {
|
|
266
|
+
const layoutId = typeof layoutSpec === 'string' ? layoutSpec : layoutSpec.id;
|
|
267
|
+
const layoutProps = typeof layoutSpec === 'object' && layoutSpec !== null && 'props' in layoutSpec
|
|
268
|
+
? layoutSpec.props
|
|
269
|
+
: undefined;
|
|
270
|
+
try {
|
|
271
|
+
const layout = this.layoutLoader.load(layoutId, layoutProps);
|
|
272
|
+
const providerRaw = agent.provider;
|
|
273
|
+
const providerList = Array.isArray(providerRaw)
|
|
274
|
+
? providerRaw
|
|
275
|
+
: (typeof providerRaw === 'string' && providerRaw.length > 0)
|
|
276
|
+
? [providerRaw]
|
|
277
|
+
: [];
|
|
278
|
+
const providerDisplay = providerList.length > 0
|
|
279
|
+
? providerList.join(', ')
|
|
280
|
+
: (typeof providerRaw === 'string' ? providerRaw : '');
|
|
281
|
+
const inlineConfig = agent.inline
|
|
282
|
+
? { ...agent.inline, prompt: baseSystemPrompt }
|
|
283
|
+
: { prompt: baseSystemPrompt };
|
|
284
|
+
const templateOptions = [];
|
|
285
|
+
const sessionInfo = {
|
|
286
|
+
mode: templateContext.mode ?? 'query',
|
|
287
|
+
platform: templateContext.platform ?? 'cli',
|
|
288
|
+
options: templateOptions,
|
|
289
|
+
env: templateContext.env ?? {},
|
|
290
|
+
vars: templateContext.vars ?? {},
|
|
291
|
+
tools: templateContext.tools ?? null,
|
|
292
|
+
};
|
|
293
|
+
const agentSkills = await this.skillLoaderService.loadAgentSkills(agent.skills);
|
|
294
|
+
const renderContext = {
|
|
295
|
+
user_input: templateContext.user_input,
|
|
296
|
+
agent: {
|
|
297
|
+
id: agent.id,
|
|
298
|
+
name: agent.name || agent.id,
|
|
299
|
+
role: agent.role || '',
|
|
300
|
+
team: agent.team || '',
|
|
301
|
+
description: agent.description || '',
|
|
302
|
+
workingDirectory: agent.workingDirectory,
|
|
303
|
+
capabilities: agent.capabilities || [],
|
|
304
|
+
specialties: agent.specialties || [],
|
|
305
|
+
provider: providerDisplay,
|
|
306
|
+
providerList,
|
|
307
|
+
providerRaw,
|
|
308
|
+
inline: inlineConfig,
|
|
309
|
+
model: agent.inline?.model,
|
|
310
|
+
options: agent.options ?? {},
|
|
311
|
+
optionsArray: Array.isArray(agent.options) ? agent.options : undefined,
|
|
312
|
+
optionsByMode: !Array.isArray(agent.options) && typeof agent.options === 'object'
|
|
313
|
+
? agent.options
|
|
314
|
+
: undefined,
|
|
315
|
+
remote: agent.remote ?? null,
|
|
316
|
+
documents: agent.inline && 'documents' in agent.inline ? agent.inline.documents : undefined,
|
|
317
|
+
},
|
|
318
|
+
documents: documentsForTemplate,
|
|
319
|
+
skills: agentSkills,
|
|
320
|
+
vars: templateContext.vars || {},
|
|
321
|
+
props: layoutProps ?? {},
|
|
322
|
+
messages: templateContext.messages || [],
|
|
323
|
+
platform: templateContext.platform ?? 'cli',
|
|
324
|
+
tools: templateContext.tools,
|
|
325
|
+
session: sessionInfo,
|
|
326
|
+
env: templateContext.env ?? {},
|
|
327
|
+
metadata: templateContext.metadata ?? {},
|
|
328
|
+
context: {
|
|
329
|
+
mode: templateContext.mode ?? 'query',
|
|
330
|
+
platform: templateContext.platform ?? 'cli',
|
|
331
|
+
options: templateOptions,
|
|
332
|
+
env: templateContext.env ?? {},
|
|
333
|
+
vars: templateContext.vars ?? {},
|
|
334
|
+
agent: templateContext.agent ?? null,
|
|
335
|
+
},
|
|
336
|
+
};
|
|
337
|
+
renderContext.layout = {
|
|
338
|
+
system_prompt: baseSystemPrompt,
|
|
339
|
+
prompt: baseSystemPrompt,
|
|
340
|
+
};
|
|
341
|
+
const rendered = this.layoutRenderer.render(layout, renderContext);
|
|
342
|
+
this.logger.debug(`Layout rendered successfully for agent ${agent.id}`);
|
|
343
|
+
const { processDocumentTemplate } = await Promise.resolve().then(() => __importStar(require('./utils/template-processor')));
|
|
344
|
+
const finalSystemPrompt = await processDocumentTemplate(rendered, this.documentLoaderService, { ...templateContext, documents: documentsForTemplate });
|
|
345
|
+
return finalSystemPrompt;
|
|
346
|
+
}
|
|
347
|
+
catch (error) {
|
|
348
|
+
const layoutIdForLog = typeof layoutSpec === 'string' ? layoutSpec : layoutSpec.id;
|
|
349
|
+
console.error(`❌ [Layout Error] Failed to process layout (${layoutIdForLog}) for agent ${agent.id}:`, (0, crewx_sdk_1.getErrorMessage)(error));
|
|
350
|
+
this.logger.warn(`Failed to process layout (${layoutIdForLog}) for agent ${agent.id}: ${(0, crewx_sdk_1.getErrorMessage)(error)}`);
|
|
351
|
+
if (inlineLayout) {
|
|
352
|
+
console.log('[Layout Fallback] Using inline.system_prompt');
|
|
353
|
+
this.logger.warn('Falling back to inline.system_prompt');
|
|
354
|
+
}
|
|
355
|
+
else {
|
|
356
|
+
console.log('[Layout Fallback] Using default system prompt');
|
|
357
|
+
this.logger.warn('Falling back to default system prompt');
|
|
358
|
+
}
|
|
359
|
+
}
|
|
360
|
+
}
|
|
361
|
+
let systemPrompt = baseSystemPrompt;
|
|
362
|
+
if (systemPrompt) {
|
|
363
|
+
const { processDocumentTemplate } = await Promise.resolve().then(() => __importStar(require('./utils/template-processor')));
|
|
364
|
+
systemPrompt = await processDocumentTemplate(systemPrompt, this.documentLoaderService, { ...templateContext, documents: documentsForTemplate });
|
|
365
|
+
}
|
|
366
|
+
return systemPrompt;
|
|
367
|
+
}
|
|
368
|
+
async getTaskLogs(input) {
|
|
369
|
+
const { taskId } = input || {};
|
|
370
|
+
this.logger.log('=== getTaskLogs called ===');
|
|
371
|
+
this.logger.log(`Input taskId: ${taskId}`);
|
|
372
|
+
try {
|
|
373
|
+
const logsContent = this.taskManagementService.getTaskLogsFromFile(taskId);
|
|
374
|
+
return {
|
|
375
|
+
content: [{ type: 'text', text: logsContent }],
|
|
376
|
+
isError: false
|
|
377
|
+
};
|
|
378
|
+
}
|
|
379
|
+
catch (error) {
|
|
380
|
+
this.logger.error('Error reading logs:', error);
|
|
381
|
+
return {
|
|
382
|
+
content: [{ type: 'text', text: `Error reading logs: ${error.message}` }],
|
|
383
|
+
isError: true
|
|
384
|
+
};
|
|
385
|
+
}
|
|
386
|
+
}
|
|
387
|
+
async checkAIProviders() {
|
|
388
|
+
this.logger.log('Checking AI provider availability');
|
|
389
|
+
try {
|
|
390
|
+
const availableProviders = await this.aiService.checkAvailableProviders();
|
|
391
|
+
const installation = await this.aiService.validateCLIInstallation();
|
|
392
|
+
const recommendations = this.getInstallationRecommendations(installation);
|
|
393
|
+
const bridgeProviders = this.providerBridgeService.listAvailableProviders();
|
|
394
|
+
let bridgeStatus = '⚠️ ProviderBridge: no providers registered.';
|
|
395
|
+
if (bridgeProviders.length > 0) {
|
|
396
|
+
try {
|
|
397
|
+
const { resolution } = await this.providerBridgeService.createAgentRuntime({
|
|
398
|
+
provider: bridgeProviders[0],
|
|
399
|
+
defaultAgentId: 'provider-bridge-check',
|
|
400
|
+
});
|
|
401
|
+
bridgeStatus = `✅ ProviderBridge ready (${resolution.provider.name})`;
|
|
402
|
+
}
|
|
403
|
+
catch (error) {
|
|
404
|
+
const message = error instanceof Error ? error.message : String(error);
|
|
405
|
+
bridgeStatus = `❌ ProviderBridge error: ${message}`;
|
|
406
|
+
}
|
|
407
|
+
}
|
|
408
|
+
const responseText = `🤖 **AI Providers Status**
|
|
409
|
+
|
|
410
|
+
**Available Providers:**
|
|
411
|
+
${availableProviders.length > 0 ? availableProviders.map(p => `✅ ${p}`).join('\n') : '❌ No providers available'}
|
|
412
|
+
|
|
413
|
+
**Provider Bridge:**
|
|
414
|
+
${bridgeStatus}${bridgeProviders.length > 0 ? `\nRegistered: ${bridgeProviders.join(', ')}` : ''}
|
|
415
|
+
|
|
416
|
+
**Installation Status:**
|
|
417
|
+
• Claude CLI: ${installation.claude ? '✅ Installed' : '❌ Not Installed'}
|
|
418
|
+
• Gemini CLI: ${installation.gemini ? '✅ Installed' : '❌ Not Installed'}
|
|
419
|
+
• Copilot CLI: ${installation.copilot ? '✅ Installed' : '❌ Not Installed'}
|
|
420
|
+
|
|
421
|
+
**Recommendations:**
|
|
422
|
+
${recommendations.map(r => `• ${r}`).join('\n')}`;
|
|
423
|
+
return {
|
|
424
|
+
content: [
|
|
425
|
+
{
|
|
426
|
+
type: 'text',
|
|
427
|
+
text: responseText
|
|
428
|
+
}
|
|
429
|
+
],
|
|
430
|
+
success: true,
|
|
431
|
+
availableProviders,
|
|
432
|
+
installation: {
|
|
433
|
+
claude: installation.claude,
|
|
434
|
+
gemini: installation.gemini,
|
|
435
|
+
copilot: installation.copilot,
|
|
436
|
+
},
|
|
437
|
+
providerBridge: {
|
|
438
|
+
status: bridgeStatus,
|
|
439
|
+
providers: bridgeProviders,
|
|
440
|
+
},
|
|
441
|
+
recommendations,
|
|
442
|
+
};
|
|
443
|
+
}
|
|
444
|
+
catch (error) {
|
|
445
|
+
const errorMessage = (0, crewx_sdk_1.getErrorMessage)(error);
|
|
446
|
+
this.logger.error(`Provider check failed: ${errorMessage}`, (0, crewx_sdk_1.getErrorStack)(error));
|
|
447
|
+
return {
|
|
448
|
+
content: [
|
|
449
|
+
{
|
|
450
|
+
type: 'text',
|
|
451
|
+
text: `❌ **AI Providers Check Failed**
|
|
452
|
+
|
|
453
|
+
**Error:** ${errorMessage}
|
|
454
|
+
|
|
455
|
+
No AI providers could be verified.`
|
|
456
|
+
}
|
|
457
|
+
],
|
|
458
|
+
success: false,
|
|
459
|
+
error: errorMessage,
|
|
460
|
+
availableProviders: [],
|
|
461
|
+
installation: {
|
|
462
|
+
claude: { installed: false },
|
|
463
|
+
gemini: { installed: false },
|
|
464
|
+
copilot: { installed: false }
|
|
465
|
+
},
|
|
466
|
+
providerBridge: {
|
|
467
|
+
status: '❌ ProviderBridge inspection skipped due to error',
|
|
468
|
+
providers: [],
|
|
469
|
+
},
|
|
470
|
+
};
|
|
471
|
+
}
|
|
472
|
+
}
|
|
473
|
+
getInstallationRecommendations(installation) {
|
|
474
|
+
const recommendations = [];
|
|
475
|
+
if (!installation.claude) {
|
|
476
|
+
recommendations.push('Claude CLI installation: npm install -g @anthropic-ai/claude-code');
|
|
477
|
+
}
|
|
478
|
+
if (!installation.gemini) {
|
|
479
|
+
recommendations.push('Gemini CLI installation: npm install -g @google/gemini-cli');
|
|
480
|
+
}
|
|
481
|
+
if (!installation.copilot) {
|
|
482
|
+
recommendations.push('GitHub Copilot CLI installation: npm install -g @github/copilot-cli or gh extension install github/gh-copilot');
|
|
483
|
+
}
|
|
484
|
+
if (installation.claude && installation.gemini && installation.copilot) {
|
|
485
|
+
recommendations.push('All AI providers are available!');
|
|
486
|
+
}
|
|
487
|
+
return recommendations;
|
|
488
|
+
}
|
|
489
|
+
async listAgents() {
|
|
490
|
+
try {
|
|
491
|
+
const agents = await this.agentLoaderService.getAllAgents();
|
|
492
|
+
this.logger.log(`Retrieved ${agents.length} available agents`);
|
|
493
|
+
const agentsConfigPath = process.env.CREWX_CONFIG;
|
|
494
|
+
let yamlContent = '';
|
|
495
|
+
if (agentsConfigPath) {
|
|
496
|
+
try {
|
|
497
|
+
const { readFile } = await Promise.resolve().then(() => __importStar(require('fs/promises')));
|
|
498
|
+
yamlContent = await readFile(agentsConfigPath, 'utf-8');
|
|
499
|
+
}
|
|
500
|
+
catch (error) {
|
|
501
|
+
this.logger.warn('Could not read YAML file for display:', (0, crewx_sdk_1.getErrorMessage)(error));
|
|
502
|
+
}
|
|
503
|
+
}
|
|
504
|
+
const responseText = `🤖 **Available AI Agents (${agents.length} total)**
|
|
505
|
+
|
|
506
|
+
**Configuration Source:** ${process.env.CREWX_CONFIG ? 'External YAML file' : 'Built-in defaults'}
|
|
507
|
+
${process.env.CREWX_CONFIG ? `**Config Path:** \`${process.env.CREWX_CONFIG}\`` : ''}
|
|
508
|
+
|
|
509
|
+
**Parsed Agent Summary:**
|
|
510
|
+
${agents.map((agent, index) => `${index + 1}. **${agent.id}**
|
|
511
|
+
- Provider: ${agent.provider}
|
|
512
|
+
- Working Dir: ${agent.workingDirectory}
|
|
513
|
+
${agent.name ? `- Name: ${agent.name}` : ''}
|
|
514
|
+
${agent.role ? `- Role: ${agent.role}` : ''}
|
|
515
|
+
${agent.team ? `- Team: ${agent.team}` : ''}
|
|
516
|
+
`).join('')}
|
|
517
|
+
|
|
518
|
+
${yamlContent ? `**Full YAML Configuration:**
|
|
519
|
+
\`\`\`yaml
|
|
520
|
+
${yamlContent}
|
|
521
|
+
\`\`\`
|
|
522
|
+
|
|
523
|
+
**💡 Customization Guide:**
|
|
524
|
+
You can customize agents by modifying the YAML file. Required fields:
|
|
525
|
+
- \`id\`: Unique identifier
|
|
526
|
+
- \`working_directory\`: Path for agent operations
|
|
527
|
+
- \`inline.provider\`: AI provider (claude/gemini/copilot)
|
|
528
|
+
- \`inline.system_prompt\`: Agent's specialized instructions
|
|
529
|
+
|
|
530
|
+
Optional fields (like \`name\`, \`role\`, \`team\`, etc.) can be added for better organization.` : `**Default Configuration:**
|
|
531
|
+
No external YAML file configured. Using built-in agents.
|
|
532
|
+
Set \`CREWX_CONFIG\` environment variable to use custom agents.
|
|
533
|
+
|
|
534
|
+
**Example YAML Structure:**
|
|
535
|
+
\`\`\`yaml
|
|
536
|
+
agents:
|
|
537
|
+
- id: "your_agent_id"
|
|
538
|
+
name: "Your Agent Name"
|
|
539
|
+
role: "specialist"
|
|
540
|
+
working_directory: "/path/to/project"
|
|
541
|
+
inline:
|
|
542
|
+
type: "agent"
|
|
543
|
+
provider: "claude"
|
|
544
|
+
system_prompt: |
|
|
545
|
+
You are a specialized AI agent for...
|
|
546
|
+
\`\`\``}
|
|
547
|
+
|
|
548
|
+
**Recommendations:**
|
|
549
|
+
|
|
550
|
+
**🚀 Performance Tip:** For optimal results, formulate queries in English. Testing shows English queries typically produce more detailed responses, faster processing times (20% improvement), and higher success rates compared to other languages.
|
|
551
|
+
|
|
552
|
+
**Configuration Source:** ${process.env.CREWX_CONFIG ? 'External YAML file' : 'Default hardcoded values'}`;
|
|
553
|
+
return {
|
|
554
|
+
content: [
|
|
555
|
+
{
|
|
556
|
+
type: 'text',
|
|
557
|
+
text: responseText
|
|
558
|
+
}
|
|
559
|
+
],
|
|
560
|
+
success: true,
|
|
561
|
+
availableAgents: agents,
|
|
562
|
+
totalCount: agents.length,
|
|
563
|
+
configurationSource: process.env.CREWX_CONFIG ? 'External YAML file' : 'Default hardcoded values'
|
|
564
|
+
};
|
|
565
|
+
}
|
|
566
|
+
catch (error) {
|
|
567
|
+
const errorMessage = (0, crewx_sdk_1.getErrorMessage)(error);
|
|
568
|
+
this.logger.error('Agent listing failed:', errorMessage);
|
|
569
|
+
return {
|
|
570
|
+
content: [
|
|
571
|
+
{
|
|
572
|
+
type: 'text',
|
|
573
|
+
text: `❌ **Error loading agents:** ${errorMessage}
|
|
574
|
+
|
|
575
|
+
**Fallback:** No agents available due to configuration error.`
|
|
576
|
+
}
|
|
577
|
+
],
|
|
578
|
+
success: false,
|
|
579
|
+
error: errorMessage,
|
|
580
|
+
availableAgents: [],
|
|
581
|
+
totalCount: 0
|
|
582
|
+
};
|
|
583
|
+
}
|
|
584
|
+
}
|
|
585
|
+
async queryAgent(args) {
|
|
586
|
+
const { agentId, query, context, model, messages, platform, metadata } = args || {};
|
|
587
|
+
if (!agentId || !query) {
|
|
588
|
+
const missingParams = [];
|
|
589
|
+
if (!agentId)
|
|
590
|
+
missingParams.push('agentId');
|
|
591
|
+
if (!query)
|
|
592
|
+
missingParams.push('query');
|
|
593
|
+
this.logger.error(`[queryAgent] Missing required parameters: ${missingParams.join(', ')}`);
|
|
594
|
+
this.logger.debug(`[queryAgent] Received args: ${JSON.stringify(args)}`);
|
|
595
|
+
return {
|
|
596
|
+
content: [
|
|
597
|
+
{
|
|
598
|
+
type: 'text',
|
|
599
|
+
text: `❌ **Parameter Validation Failed**
|
|
600
|
+
|
|
601
|
+
**Error:** Missing required parameters: ${missingParams.join(', ')}
|
|
602
|
+
|
|
603
|
+
**Received Arguments:**
|
|
604
|
+
\`\`\`json
|
|
605
|
+
${JSON.stringify(args, null, 2)}
|
|
606
|
+
\`\`\`
|
|
607
|
+
|
|
608
|
+
**Expected Parameters:**
|
|
609
|
+
- \`agentId\` (required): Agent ID to query
|
|
610
|
+
- \`query\` (required): Question or request to ask the agent
|
|
611
|
+
|
|
612
|
+
Please ensure the MCP client is sending the correct JSON-RPC request format:
|
|
613
|
+
\`\`\`json
|
|
614
|
+
{
|
|
615
|
+
"jsonrpc": "2.0",
|
|
616
|
+
"id": 1,
|
|
617
|
+
"method": "tools/call",
|
|
618
|
+
"params": {
|
|
619
|
+
"name": "crewx_queryAgent",
|
|
620
|
+
"arguments": {
|
|
621
|
+
"agentId": "your-agent-id",
|
|
622
|
+
"query": "your question here"
|
|
623
|
+
}
|
|
624
|
+
}
|
|
625
|
+
}
|
|
626
|
+
\`\`\``
|
|
627
|
+
}
|
|
628
|
+
],
|
|
629
|
+
success: false,
|
|
630
|
+
error: `Missing required parameters: ${missingParams.join(', ')}`,
|
|
631
|
+
missingParameters: missingParams,
|
|
632
|
+
receivedArgs: args,
|
|
633
|
+
readOnlyMode: true,
|
|
634
|
+
isError: true
|
|
635
|
+
};
|
|
636
|
+
}
|
|
637
|
+
let taskId;
|
|
638
|
+
let traceTaskId = null;
|
|
639
|
+
let traceCompleted = false;
|
|
640
|
+
try {
|
|
641
|
+
const agents = await this.agentLoaderService.getAllAgents();
|
|
642
|
+
const agent = agents.find(a => a.id === agentId);
|
|
643
|
+
const agentProvider = agent
|
|
644
|
+
? (Array.isArray(agent.provider) ? agent.provider[0] : agent.provider) || 'claude'
|
|
645
|
+
: 'claude';
|
|
646
|
+
taskId = this.taskManagementService.createTask({
|
|
647
|
+
type: 'query',
|
|
648
|
+
provider: agentProvider,
|
|
649
|
+
prompt: query,
|
|
650
|
+
agentId: agentId
|
|
651
|
+
});
|
|
652
|
+
process.env.CREWX_TASK_ID = taskId;
|
|
653
|
+
const agentDescriptor = model ? `${agentId} (model: ${model})` : agentId;
|
|
654
|
+
this.taskManagementService.addTaskLog(taskId, { level: 'info', message: `Started query agent ${agentDescriptor}` });
|
|
655
|
+
const fileRemoteWs = agent ? this.resolveFileRemoteAgent(agent, agentId, taskId) : {};
|
|
656
|
+
const inheritedTraceId = process.env.CREWX_TRACE_ID;
|
|
657
|
+
const inheritedParentTaskId = process.env.CREWX_PARENT_TASK_ID;
|
|
658
|
+
const inheritedCallerAgentId = process.env.CREWX_CALLER_AGENT_ID;
|
|
659
|
+
const traceId = inheritedTraceId || crypto.randomUUID();
|
|
660
|
+
const resolvedModel = model ?? agent?.inline?.model ?? undefined;
|
|
661
|
+
traceTaskId = this.tracingService?.createTask({
|
|
662
|
+
id: taskId,
|
|
663
|
+
agent_id: agentId,
|
|
664
|
+
prompt: query,
|
|
665
|
+
mode: 'query',
|
|
666
|
+
model: resolvedModel,
|
|
667
|
+
platform: platform ?? 'cli',
|
|
668
|
+
crewx_version: version_1.CREWX_VERSION,
|
|
669
|
+
trace_id: traceId,
|
|
670
|
+
parent_task_id: inheritedParentTaskId,
|
|
671
|
+
caller_agent_id: inheritedCallerAgentId,
|
|
672
|
+
metadata: { provider: agentProvider, provider_version: undefined },
|
|
673
|
+
command: process.argv.join(' '),
|
|
674
|
+
thread_id: metadata?.thread,
|
|
675
|
+
workspace_id: fileRemoteWs.workspaceId,
|
|
676
|
+
workspace_name: fileRemoteWs.workspaceName,
|
|
677
|
+
}) ?? null;
|
|
678
|
+
this.logger.log(`[${taskId}] Querying agent ${agentId}: ${query.substring(0, 50)}...`);
|
|
679
|
+
this.taskManagementService.addTaskLog(taskId, { level: 'info', message: `Query: ${query.substring(0, 100)}...` });
|
|
680
|
+
if (model) {
|
|
681
|
+
this.taskManagementService.addTaskLog(taskId, { level: 'info', message: `Model: ${model}` });
|
|
682
|
+
}
|
|
683
|
+
if (!agent) {
|
|
684
|
+
if (traceTaskId) {
|
|
685
|
+
this.tracingService?.failTask(traceTaskId, `Agent '${agentId}' not found`);
|
|
686
|
+
traceCompleted = true;
|
|
687
|
+
}
|
|
688
|
+
return {
|
|
689
|
+
content: [
|
|
690
|
+
{
|
|
691
|
+
type: 'text',
|
|
692
|
+
text: `❌ **Agent Not Found**
|
|
693
|
+
|
|
694
|
+
**Error:** Agent '${agentId}' not found.
|
|
695
|
+
|
|
696
|
+
**Available Agents:** ${agents.map(a => a.id).join(', ')}
|
|
697
|
+
|
|
698
|
+
Please check the agent ID and try again.`
|
|
699
|
+
}
|
|
700
|
+
],
|
|
701
|
+
success: false,
|
|
702
|
+
agent: agentId,
|
|
703
|
+
error: `Agent '${agentId}' not found`,
|
|
704
|
+
availableAgents: agents.map(a => a.id),
|
|
705
|
+
readOnlyMode: true
|
|
706
|
+
};
|
|
707
|
+
}
|
|
708
|
+
if (agent.remote?.type === 'mcp-http') {
|
|
709
|
+
try {
|
|
710
|
+
const remoteResult = await this.remoteAgentService.queryRemoteAgent(agent, {
|
|
711
|
+
query,
|
|
712
|
+
context,
|
|
713
|
+
model,
|
|
714
|
+
platform,
|
|
715
|
+
messages,
|
|
716
|
+
});
|
|
717
|
+
const normalized = this.normalizeRemoteResult(agent, taskId, remoteResult, true);
|
|
718
|
+
const logLevel = normalized.success ? 'info' : 'error';
|
|
719
|
+
this.taskManagementService.addTaskLog(taskId, {
|
|
720
|
+
level: logLevel,
|
|
721
|
+
message: normalized.success
|
|
722
|
+
? 'Remote agent query completed successfully'
|
|
723
|
+
: `Remote agent query failed: ${normalized.error || 'Unknown error'}`,
|
|
724
|
+
});
|
|
725
|
+
this.taskManagementService.completeTask(taskId, normalized, normalized.success !== false);
|
|
726
|
+
if (traceTaskId) {
|
|
727
|
+
if (normalized.success !== false) {
|
|
728
|
+
this.tracingService?.completeTask(traceTaskId, (0, extract_text_1.extractTextFromContent)(normalized.content), normalized.exitCode);
|
|
729
|
+
}
|
|
730
|
+
else {
|
|
731
|
+
this.tracingService?.failTask(traceTaskId, normalized.error || 'Unknown error', normalized.exitCode);
|
|
732
|
+
}
|
|
733
|
+
traceCompleted = true;
|
|
734
|
+
}
|
|
735
|
+
return normalized;
|
|
736
|
+
}
|
|
737
|
+
catch (error) {
|
|
738
|
+
const errorMessage = (0, crewx_sdk_1.getErrorMessage)(error);
|
|
739
|
+
this.taskManagementService.addTaskLog(taskId, {
|
|
740
|
+
level: 'error',
|
|
741
|
+
message: `Remote agent query failed: ${errorMessage}`,
|
|
742
|
+
});
|
|
743
|
+
this.taskManagementService.completeTask(taskId, { success: false, error: errorMessage }, false);
|
|
744
|
+
if (traceTaskId) {
|
|
745
|
+
this.tracingService?.failTask(traceTaskId, errorMessage);
|
|
746
|
+
traceCompleted = true;
|
|
747
|
+
}
|
|
748
|
+
return {
|
|
749
|
+
content: [
|
|
750
|
+
{
|
|
751
|
+
type: 'text',
|
|
752
|
+
text: `❌ **Remote agent error**\n\n\
|
|
753
|
+
${errorMessage}`,
|
|
754
|
+
},
|
|
755
|
+
],
|
|
756
|
+
success: false,
|
|
757
|
+
agent: agentId,
|
|
758
|
+
provider: 'remote',
|
|
759
|
+
error: errorMessage,
|
|
760
|
+
taskId,
|
|
761
|
+
readOnlyMode: true,
|
|
762
|
+
readOnly: true,
|
|
763
|
+
};
|
|
764
|
+
}
|
|
765
|
+
}
|
|
766
|
+
const workingDir = agent.workingDirectory || process.cwd();
|
|
767
|
+
const securityKey = this.generateSecurityKey();
|
|
768
|
+
const contextMessages = messages && messages.length > 0 ? messages : [];
|
|
769
|
+
const documents = {};
|
|
770
|
+
const docNames = this.documentLoaderService.getDocumentNames();
|
|
771
|
+
for (const docName of docNames) {
|
|
772
|
+
const content = await this.documentLoaderService.getDocumentContent(docName);
|
|
773
|
+
const toc = await this.documentLoaderService.getDocumentToc(docName);
|
|
774
|
+
if (content) {
|
|
775
|
+
documents[docName] = { content, toc };
|
|
776
|
+
}
|
|
777
|
+
}
|
|
778
|
+
const templateContext = {
|
|
779
|
+
user_input: query,
|
|
780
|
+
messages: contextMessages,
|
|
781
|
+
agent: {
|
|
782
|
+
id: agent.id,
|
|
783
|
+
name: agent.name || agent.id,
|
|
784
|
+
provider: (Array.isArray(agent.provider) ? agent.provider[0] : agent.provider) || 'claude',
|
|
785
|
+
model: model || agent.inline?.model,
|
|
786
|
+
workingDirectory: workingDir,
|
|
787
|
+
inline: {
|
|
788
|
+
prompt: agent.inline?.prompt || agent.inline?.system_prompt || agent.systemPrompt || '',
|
|
789
|
+
},
|
|
790
|
+
specialties: agent.specialties,
|
|
791
|
+
capabilities: agent.capabilities,
|
|
792
|
+
description: agent.description,
|
|
793
|
+
},
|
|
794
|
+
documents,
|
|
795
|
+
vars: {
|
|
796
|
+
security_key: securityKey,
|
|
797
|
+
},
|
|
798
|
+
props: {},
|
|
799
|
+
mode: 'query',
|
|
800
|
+
platform: platform,
|
|
801
|
+
metadata: metadata,
|
|
802
|
+
env: process.env,
|
|
803
|
+
tools: this.buildToolsContext(),
|
|
804
|
+
};
|
|
805
|
+
let systemPrompt = await this.processAgentSystemPrompt(agent, templateContext);
|
|
806
|
+
if (process.env.CREWX_APPEND_LEGACY === 'true') {
|
|
807
|
+
this.logger.debug('[WBS-14] Legacy append mode enabled (query)', {
|
|
808
|
+
agentId: agent.id,
|
|
809
|
+
layoutId: typeof agent.inline?.layout === 'string'
|
|
810
|
+
? agent.inline?.layout
|
|
811
|
+
: agent.inline?.layout?.id ?? 'crewx/default',
|
|
812
|
+
});
|
|
813
|
+
systemPrompt += `
|
|
814
|
+
|
|
815
|
+
Specialties: ${agent.specialties?.join(', ') || 'General'}
|
|
816
|
+
Capabilities: ${agent.capabilities?.join(', ') || 'Analysis'}
|
|
817
|
+
Working Directory: ${workingDir}`;
|
|
818
|
+
}
|
|
819
|
+
else if (process.env.CREWX_WBS14_TELEMETRY === 'true') {
|
|
820
|
+
this.logger.debug('[WBS-14] Metadata delegated to layout (query mode)', {
|
|
821
|
+
agentId: agent.id,
|
|
822
|
+
hasLayout: Boolean(agent.inline?.layout),
|
|
823
|
+
layoutId: typeof agent.inline?.layout === 'string'
|
|
824
|
+
? agent.inline?.layout
|
|
825
|
+
: agent.inline?.layout?.id ?? 'crewx/default',
|
|
826
|
+
specialtiesCount: agent.specialties?.length ?? 0,
|
|
827
|
+
capabilitiesCount: agent.capabilities?.length ?? 0,
|
|
828
|
+
workingDirectory: workingDir,
|
|
829
|
+
});
|
|
830
|
+
}
|
|
831
|
+
let fullPrompt = systemPrompt;
|
|
832
|
+
if (context) {
|
|
833
|
+
fullPrompt += `\n\n${context}`;
|
|
834
|
+
}
|
|
835
|
+
if (!systemPrompt.includes('<user_query')) {
|
|
836
|
+
this.logger.debug('[Legacy] Adding <user_query> wrapper manually (layout not used)');
|
|
837
|
+
fullPrompt += `\n\n<user_query key="${securityKey}">
|
|
838
|
+
${query}
|
|
839
|
+
</user_query>`;
|
|
840
|
+
}
|
|
841
|
+
if (traceTaskId) {
|
|
842
|
+
this.tracingService?.updateTaskRenderedPrompt(traceTaskId, fullPrompt);
|
|
843
|
+
}
|
|
844
|
+
const promptLength = fullPrompt.length;
|
|
845
|
+
this.taskManagementService.addTaskLog(taskId, {
|
|
846
|
+
level: 'info',
|
|
847
|
+
message: `Prompt length: ${promptLength} characters`,
|
|
848
|
+
});
|
|
849
|
+
let runtimeResult;
|
|
850
|
+
let providerResolution;
|
|
851
|
+
let providerInput;
|
|
852
|
+
if (args.provider) {
|
|
853
|
+
providerInput = args.provider;
|
|
854
|
+
}
|
|
855
|
+
else if (Array.isArray(agent.provider)) {
|
|
856
|
+
providerInput = await this.getAvailableProvider(agent.provider);
|
|
857
|
+
}
|
|
858
|
+
else if (typeof agent.provider === 'string' && agent.provider.trim().length > 0) {
|
|
859
|
+
if (agent.provider.startsWith('api/')) {
|
|
860
|
+
providerInput = agentId;
|
|
861
|
+
}
|
|
862
|
+
else {
|
|
863
|
+
providerInput = agent.provider;
|
|
864
|
+
}
|
|
865
|
+
}
|
|
866
|
+
try {
|
|
867
|
+
runtimeResult = await this.providerBridgeService.createAgentRuntime({
|
|
868
|
+
provider: providerInput,
|
|
869
|
+
defaultAgentId: agentId,
|
|
870
|
+
validAgents: agents.map(a => a.id),
|
|
871
|
+
});
|
|
872
|
+
providerResolution = runtimeResult.resolution;
|
|
873
|
+
}
|
|
874
|
+
catch (error) {
|
|
875
|
+
const errorMsg = error instanceof Error ? error.message : 'Unknown provider error';
|
|
876
|
+
this.taskManagementService.addTaskLog(taskId, {
|
|
877
|
+
level: 'error',
|
|
878
|
+
message: `Provider resolution failed: ${errorMsg}`,
|
|
879
|
+
});
|
|
880
|
+
this.taskManagementService.completeTask(taskId, { success: false, error: errorMsg }, false);
|
|
881
|
+
if (traceTaskId) {
|
|
882
|
+
this.tracingService?.failTask(traceTaskId, errorMsg);
|
|
883
|
+
traceCompleted = true;
|
|
884
|
+
}
|
|
885
|
+
return {
|
|
886
|
+
content: [
|
|
887
|
+
{
|
|
888
|
+
type: 'text',
|
|
889
|
+
text: `❌ **Provider Error**\n\n${errorMsg}\n\nAvailable providers: ${this.providerBridgeService.listAvailableProviders().join(', ')}`,
|
|
890
|
+
},
|
|
891
|
+
],
|
|
892
|
+
success: false,
|
|
893
|
+
agent: agentId,
|
|
894
|
+
provider: 'none',
|
|
895
|
+
error: errorMsg,
|
|
896
|
+
taskId,
|
|
897
|
+
readOnlyMode: true,
|
|
898
|
+
readOnly: true,
|
|
899
|
+
};
|
|
900
|
+
}
|
|
901
|
+
const resolvedProviderName = providerResolution.provider.name;
|
|
902
|
+
if (args.provider) {
|
|
903
|
+
this.taskManagementService.addTaskLog(taskId, {
|
|
904
|
+
level: 'info',
|
|
905
|
+
message: `Using CLI-specified provider: ${args.provider} (resolved to ${resolvedProviderName})`
|
|
906
|
+
});
|
|
907
|
+
}
|
|
908
|
+
else if (providerInput) {
|
|
909
|
+
this.taskManagementService.addTaskLog(taskId, {
|
|
910
|
+
level: 'info',
|
|
911
|
+
message: `Agent provider resolved to ${resolvedProviderName} (input: ${providerInput})`
|
|
912
|
+
});
|
|
913
|
+
}
|
|
914
|
+
else {
|
|
915
|
+
this.taskManagementService.addTaskLog(taskId, {
|
|
916
|
+
level: 'info',
|
|
917
|
+
message: `Using ProviderBridge fallback provider: ${resolvedProviderName}`,
|
|
918
|
+
});
|
|
919
|
+
}
|
|
920
|
+
const agentOptions = this.getOptionsForAgent(agent, 'query', resolvedProviderName);
|
|
921
|
+
const modelToUse = model || agent.inline?.model || providerResolution.defaultModel;
|
|
922
|
+
const structuredPayload = await this.buildStructuredPayload({
|
|
923
|
+
agentId,
|
|
924
|
+
provider: resolvedProviderName,
|
|
925
|
+
mode: 'query',
|
|
926
|
+
prompt: fullPrompt,
|
|
927
|
+
context,
|
|
928
|
+
messages,
|
|
929
|
+
platform: platform || 'cli',
|
|
930
|
+
model: modelToUse,
|
|
931
|
+
platformMetadata: metadata,
|
|
932
|
+
});
|
|
933
|
+
const runtimeMessages = this.toConversationMessages(messages);
|
|
934
|
+
let agentResult;
|
|
935
|
+
let pidRecorded = false;
|
|
936
|
+
const handleProcessStart = (pid) => {
|
|
937
|
+
if (!traceTaskId) {
|
|
938
|
+
return;
|
|
939
|
+
}
|
|
940
|
+
const updated = this.tracingService?.updateTaskPid(traceTaskId, pid) ?? false;
|
|
941
|
+
if (updated) {
|
|
942
|
+
pidRecorded = true;
|
|
943
|
+
}
|
|
944
|
+
};
|
|
945
|
+
try {
|
|
946
|
+
const originalLog = console.log;
|
|
947
|
+
console.log = (...args) => {
|
|
948
|
+
const message = args.map(arg => typeof arg === 'object' ? JSON.stringify(arg) : String(arg)).join(' ');
|
|
949
|
+
if (message.includes('[INFO]')) {
|
|
950
|
+
this.taskManagementService.addTaskLog(taskId, {
|
|
951
|
+
level: 'info',
|
|
952
|
+
message: message.replace('[INFO] ', ''),
|
|
953
|
+
});
|
|
954
|
+
}
|
|
955
|
+
originalLog.apply(console, args);
|
|
956
|
+
};
|
|
957
|
+
const processedEnv = await this.processAgentEnv(agent.env, agent);
|
|
958
|
+
try {
|
|
959
|
+
agentResult = await runtimeResult.runtime.agent.query({
|
|
960
|
+
agentId,
|
|
961
|
+
prompt: fullPrompt,
|
|
962
|
+
context,
|
|
963
|
+
messages: runtimeMessages,
|
|
964
|
+
model: modelToUse,
|
|
965
|
+
options: {
|
|
966
|
+
workingDirectory: workingDir,
|
|
967
|
+
timeout: this.timeoutConfig.parallel,
|
|
968
|
+
additionalArgs: agentOptions,
|
|
969
|
+
taskId,
|
|
970
|
+
securityKey,
|
|
971
|
+
pipedContext: structuredPayload,
|
|
972
|
+
env: processedEnv,
|
|
973
|
+
runtime: agent.runtime,
|
|
974
|
+
traceId,
|
|
975
|
+
onProcessStart: handleProcessStart,
|
|
976
|
+
},
|
|
977
|
+
});
|
|
978
|
+
}
|
|
979
|
+
finally {
|
|
980
|
+
console.log = originalLog;
|
|
981
|
+
}
|
|
982
|
+
}
|
|
983
|
+
catch (error) {
|
|
984
|
+
const errorMsg = error instanceof Error ? error.message : 'Agent runtime query failed';
|
|
985
|
+
this.taskManagementService.addTaskLog(taskId, {
|
|
986
|
+
level: 'error',
|
|
987
|
+
message: `Agent runtime query failed: ${errorMsg}`,
|
|
988
|
+
});
|
|
989
|
+
this.taskManagementService.completeTask(taskId, { success: false, error: errorMsg }, false);
|
|
990
|
+
if (traceTaskId) {
|
|
991
|
+
this.tracingService?.failTask(traceTaskId, errorMsg);
|
|
992
|
+
traceCompleted = true;
|
|
993
|
+
}
|
|
994
|
+
return {
|
|
995
|
+
content: [
|
|
996
|
+
{
|
|
997
|
+
type: 'text',
|
|
998
|
+
text: `❌ **Provider Error**\n\n${errorMsg}\n\nAvailable providers: ${this.providerBridgeService.listAvailableProviders().join(', ')}`,
|
|
999
|
+
},
|
|
1000
|
+
],
|
|
1001
|
+
success: false,
|
|
1002
|
+
agent: agentId,
|
|
1003
|
+
provider: resolvedProviderName,
|
|
1004
|
+
error: errorMsg,
|
|
1005
|
+
taskId,
|
|
1006
|
+
readOnlyMode: true,
|
|
1007
|
+
readOnly: true,
|
|
1008
|
+
};
|
|
1009
|
+
}
|
|
1010
|
+
const response = {
|
|
1011
|
+
success: agentResult.success,
|
|
1012
|
+
content: agentResult.content,
|
|
1013
|
+
provider: agentResult.metadata?.provider ?? resolvedProviderName,
|
|
1014
|
+
taskId: agentResult.metadata?.taskId ?? taskId,
|
|
1015
|
+
error: agentResult.metadata?.error,
|
|
1016
|
+
pid: agentResult.metadata?.pid,
|
|
1017
|
+
command: agentResult.metadata?.command,
|
|
1018
|
+
exitCode: agentResult.metadata?.exitCode,
|
|
1019
|
+
durationMs: agentResult.metadata?.durationMs,
|
|
1020
|
+
timeToFirstOutputMs: agentResult.metadata?.timeToFirstOutputMs,
|
|
1021
|
+
};
|
|
1022
|
+
if (traceTaskId && response.pid && !pidRecorded) {
|
|
1023
|
+
this.tracingService?.updateTaskPid(traceTaskId, response.pid);
|
|
1024
|
+
}
|
|
1025
|
+
if (traceTaskId && response.command) {
|
|
1026
|
+
this.tracingService?.updateTaskCodingAgentCommand(traceTaskId, response.command);
|
|
1027
|
+
}
|
|
1028
|
+
if (response.command) {
|
|
1029
|
+
this.taskManagementService.addTaskLog(taskId, {
|
|
1030
|
+
level: 'info',
|
|
1031
|
+
message: `Coding agent command: ${response.command}`,
|
|
1032
|
+
});
|
|
1033
|
+
}
|
|
1034
|
+
if (response.pid !== undefined) {
|
|
1035
|
+
this.taskManagementService.addTaskLog(taskId, {
|
|
1036
|
+
level: 'info',
|
|
1037
|
+
message: `PID: ${response.pid ?? 'unknown'}`,
|
|
1038
|
+
});
|
|
1039
|
+
}
|
|
1040
|
+
if (response.exitCode !== undefined) {
|
|
1041
|
+
this.taskManagementService.addTaskLog(taskId, {
|
|
1042
|
+
level: 'info',
|
|
1043
|
+
message: `Exit code: ${response.exitCode ?? 'unknown'}`,
|
|
1044
|
+
});
|
|
1045
|
+
}
|
|
1046
|
+
if (response.durationMs !== undefined) {
|
|
1047
|
+
this.taskManagementService.addTaskLog(taskId, {
|
|
1048
|
+
level: 'info',
|
|
1049
|
+
message: `Duration: ${response.durationMs}ms`,
|
|
1050
|
+
});
|
|
1051
|
+
}
|
|
1052
|
+
if (response.timeToFirstOutputMs !== undefined) {
|
|
1053
|
+
const firstResponseText = response.timeToFirstOutputMs === null
|
|
1054
|
+
? 'unknown'
|
|
1055
|
+
: `${response.timeToFirstOutputMs}ms`;
|
|
1056
|
+
this.taskManagementService.addTaskLog(taskId, {
|
|
1057
|
+
level: 'info',
|
|
1058
|
+
message: `First response: ${firstResponseText}`,
|
|
1059
|
+
});
|
|
1060
|
+
}
|
|
1061
|
+
this.taskManagementService.addTaskLog(taskId, { level: 'info', message: `Query completed. Success: ${response.success}` });
|
|
1062
|
+
this.taskManagementService.completeTask(taskId, response, response.success);
|
|
1063
|
+
if (traceTaskId) {
|
|
1064
|
+
if (response.success) {
|
|
1065
|
+
this.tracingService?.completeTask(traceTaskId, response.content, response.exitCode);
|
|
1066
|
+
}
|
|
1067
|
+
else {
|
|
1068
|
+
this.tracingService?.failTask(traceTaskId, response.error || 'Unknown error', response.exitCode);
|
|
1069
|
+
}
|
|
1070
|
+
traceCompleted = true;
|
|
1071
|
+
}
|
|
1072
|
+
const responseText = response.success
|
|
1073
|
+
? response.content
|
|
1074
|
+
: `❌ **Error**\n\`\`\`${response.error}\`\`\`\n\nAgent: ${agentId} (${response.provider}) · Task ID: \`${taskId}\``;
|
|
1075
|
+
return {
|
|
1076
|
+
content: [
|
|
1077
|
+
{
|
|
1078
|
+
type: 'text',
|
|
1079
|
+
text: responseText
|
|
1080
|
+
}
|
|
1081
|
+
],
|
|
1082
|
+
taskId: taskId,
|
|
1083
|
+
success: response.success,
|
|
1084
|
+
agent: agentId,
|
|
1085
|
+
provider: response.provider,
|
|
1086
|
+
query: query,
|
|
1087
|
+
response: response.content,
|
|
1088
|
+
readOnlyMode: true,
|
|
1089
|
+
error: response.error,
|
|
1090
|
+
workingDirectory: workingDir
|
|
1091
|
+
};
|
|
1092
|
+
}
|
|
1093
|
+
catch (error) {
|
|
1094
|
+
const errorMessage = (0, crewx_sdk_1.getErrorMessage)(error);
|
|
1095
|
+
if (traceTaskId) {
|
|
1096
|
+
this.tracingService?.failTask(traceTaskId, errorMessage);
|
|
1097
|
+
traceCompleted = true;
|
|
1098
|
+
}
|
|
1099
|
+
if (taskId) {
|
|
1100
|
+
this.taskManagementService.addTaskLog(taskId, { level: 'error', message: `Query failed: ${errorMessage}` });
|
|
1101
|
+
this.taskManagementService.completeTask(taskId, { error: errorMessage }, false);
|
|
1102
|
+
this.logger.error(`[${taskId}] Agent query failed for ${agentId}:`, errorMessage);
|
|
1103
|
+
}
|
|
1104
|
+
else {
|
|
1105
|
+
this.logger.error(`Agent query failed for ${agentId} (no task ID):`, errorMessage);
|
|
1106
|
+
}
|
|
1107
|
+
return {
|
|
1108
|
+
content: [
|
|
1109
|
+
{
|
|
1110
|
+
type: 'text',
|
|
1111
|
+
text: `❌ **Agent Query Failed**
|
|
1112
|
+
|
|
1113
|
+
${taskId ? `**Task ID:** ${taskId}\n` : ''}**Agent:** ${agentId}
|
|
1114
|
+
**Error:** ${errorMessage}
|
|
1115
|
+
**Query:** ${query}
|
|
1116
|
+
|
|
1117
|
+
Read-Only Mode: No files were modified.`
|
|
1118
|
+
}
|
|
1119
|
+
],
|
|
1120
|
+
success: false,
|
|
1121
|
+
agent: args.agentId,
|
|
1122
|
+
error: errorMessage,
|
|
1123
|
+
readOnlyMode: true
|
|
1124
|
+
};
|
|
1125
|
+
}
|
|
1126
|
+
finally {
|
|
1127
|
+
if (!traceCompleted && traceTaskId) {
|
|
1128
|
+
this.tracingService?.failTask(traceTaskId, 'unexpected exit');
|
|
1129
|
+
}
|
|
1130
|
+
}
|
|
1131
|
+
}
|
|
1132
|
+
async executeAgent(args) {
|
|
1133
|
+
const { agentId, task, projectPath, context, model, messages, platform, metadata } = args || {};
|
|
1134
|
+
if (!agentId || !task) {
|
|
1135
|
+
const missingParams = [];
|
|
1136
|
+
if (!agentId)
|
|
1137
|
+
missingParams.push('agentId');
|
|
1138
|
+
if (!task)
|
|
1139
|
+
missingParams.push('task');
|
|
1140
|
+
this.logger.error(`[executeAgent] Missing required parameters: ${missingParams.join(', ')}`);
|
|
1141
|
+
this.logger.debug(`[executeAgent] Received args: ${JSON.stringify(args)}`);
|
|
1142
|
+
return {
|
|
1143
|
+
content: [
|
|
1144
|
+
{
|
|
1145
|
+
type: 'text',
|
|
1146
|
+
text: `❌ **Parameter Validation Failed**
|
|
1147
|
+
|
|
1148
|
+
**Error:** Missing required parameters: ${missingParams.join(', ')}
|
|
1149
|
+
|
|
1150
|
+
**Received Arguments:**
|
|
1151
|
+
\`\`\`json
|
|
1152
|
+
${JSON.stringify(args, null, 2)}
|
|
1153
|
+
\`\`\`
|
|
1154
|
+
|
|
1155
|
+
**Expected Parameters:**
|
|
1156
|
+
- \`agentId\` (required): Agent ID to execute
|
|
1157
|
+
- \`task\` (required): Task or implementation request for the agent
|
|
1158
|
+
|
|
1159
|
+
Please ensure the MCP client is sending the correct JSON-RPC request format:
|
|
1160
|
+
\`\`\`json
|
|
1161
|
+
{
|
|
1162
|
+
"jsonrpc": "2.0",
|
|
1163
|
+
"id": 1,
|
|
1164
|
+
"method": "tools/call",
|
|
1165
|
+
"params": {
|
|
1166
|
+
"name": "crewx_executeAgent",
|
|
1167
|
+
"arguments": {
|
|
1168
|
+
"agentId": "your-agent-id",
|
|
1169
|
+
"task": "your task description here"
|
|
1170
|
+
}
|
|
1171
|
+
}
|
|
1172
|
+
}
|
|
1173
|
+
\`\`\``
|
|
1174
|
+
}
|
|
1175
|
+
],
|
|
1176
|
+
success: false,
|
|
1177
|
+
error: `Missing required parameters: ${missingParams.join(', ')}`,
|
|
1178
|
+
missingParameters: missingParams,
|
|
1179
|
+
receivedArgs: args,
|
|
1180
|
+
executionMode: true,
|
|
1181
|
+
isError: true
|
|
1182
|
+
};
|
|
1183
|
+
}
|
|
1184
|
+
let taskId;
|
|
1185
|
+
let traceTaskId = null;
|
|
1186
|
+
let traceCompleted = false;
|
|
1187
|
+
try {
|
|
1188
|
+
const agents = await this.agentLoaderService.getAllAgents();
|
|
1189
|
+
const agent = agents.find(a => a.id === agentId);
|
|
1190
|
+
const agentProvider = agent
|
|
1191
|
+
? (Array.isArray(agent.provider) ? agent.provider[0] : agent.provider) || 'claude'
|
|
1192
|
+
: 'claude';
|
|
1193
|
+
taskId = this.taskManagementService.createTask({
|
|
1194
|
+
type: 'execute',
|
|
1195
|
+
provider: agentProvider,
|
|
1196
|
+
prompt: task,
|
|
1197
|
+
agentId: agentId
|
|
1198
|
+
});
|
|
1199
|
+
process.env.CREWX_TASK_ID = taskId;
|
|
1200
|
+
const agentDescriptor = model ? `${agentId} (model: ${model})` : agentId;
|
|
1201
|
+
this.taskManagementService.addTaskLog(taskId, { level: 'info', message: `Started execute agent ${agentDescriptor}` });
|
|
1202
|
+
const fileRemoteWs = agent ? this.resolveFileRemoteAgent(agent, agentId, taskId) : {};
|
|
1203
|
+
const inheritedTraceId = process.env.CREWX_TRACE_ID;
|
|
1204
|
+
const inheritedParentTaskId = metadata && 'parentTaskId' in metadata
|
|
1205
|
+
? (metadata.parentTaskId ?? null)
|
|
1206
|
+
: process.env.CREWX_PARENT_TASK_ID;
|
|
1207
|
+
const inheritedCallerAgentId = process.env.CREWX_CALLER_AGENT_ID;
|
|
1208
|
+
const traceId = inheritedTraceId || crypto.randomUUID();
|
|
1209
|
+
const resolvedModel = model ?? agent?.inline?.model ?? undefined;
|
|
1210
|
+
traceTaskId = this.tracingService?.createTask({
|
|
1211
|
+
id: taskId,
|
|
1212
|
+
agent_id: agentId,
|
|
1213
|
+
prompt: task,
|
|
1214
|
+
mode: 'execute',
|
|
1215
|
+
model: resolvedModel,
|
|
1216
|
+
platform: platform ?? 'cli',
|
|
1217
|
+
crewx_version: version_1.CREWX_VERSION,
|
|
1218
|
+
trace_id: traceId,
|
|
1219
|
+
parent_task_id: inheritedParentTaskId,
|
|
1220
|
+
caller_agent_id: inheritedCallerAgentId,
|
|
1221
|
+
metadata: { provider: agentProvider, provider_version: undefined },
|
|
1222
|
+
command: process.argv.join(' '),
|
|
1223
|
+
thread_id: metadata?.thread,
|
|
1224
|
+
workspace_id: fileRemoteWs.workspaceId,
|
|
1225
|
+
workspace_name: fileRemoteWs.workspaceName,
|
|
1226
|
+
}) ?? null;
|
|
1227
|
+
this.logger.log(`[${taskId}] Executing agent ${agentId}: ${task.substring(0, 50)}...`);
|
|
1228
|
+
this.taskManagementService.addTaskLog(taskId, { level: 'info', message: `Task: ${task.substring(0, 100)}...` });
|
|
1229
|
+
if (model) {
|
|
1230
|
+
this.taskManagementService.addTaskLog(taskId, { level: 'info', message: `Model: ${model}` });
|
|
1231
|
+
}
|
|
1232
|
+
if (!agent) {
|
|
1233
|
+
if (traceTaskId) {
|
|
1234
|
+
this.tracingService?.failTask(traceTaskId, `Agent '${agentId}' not found`);
|
|
1235
|
+
traceCompleted = true;
|
|
1236
|
+
}
|
|
1237
|
+
return {
|
|
1238
|
+
content: [
|
|
1239
|
+
{
|
|
1240
|
+
type: 'text',
|
|
1241
|
+
text: `❌ **Agent Not Found**
|
|
1242
|
+
|
|
1243
|
+
**Error:** Agent '${agentId}' not found.
|
|
1244
|
+
|
|
1245
|
+
**Available Agents:** ${agents.map(a => a.id).join(', ')}
|
|
1246
|
+
|
|
1247
|
+
Please check the agent ID and try again.`
|
|
1248
|
+
}
|
|
1249
|
+
],
|
|
1250
|
+
success: false,
|
|
1251
|
+
agent: agentId,
|
|
1252
|
+
error: `Agent '${agentId}' not found`,
|
|
1253
|
+
availableAgents: agents.map(a => a.id),
|
|
1254
|
+
executionMode: true
|
|
1255
|
+
};
|
|
1256
|
+
}
|
|
1257
|
+
if (agent.remote?.type === 'mcp-http') {
|
|
1258
|
+
try {
|
|
1259
|
+
const remoteResult = await this.remoteAgentService.executeRemoteAgent(agent, {
|
|
1260
|
+
task,
|
|
1261
|
+
context,
|
|
1262
|
+
model,
|
|
1263
|
+
platform,
|
|
1264
|
+
messages,
|
|
1265
|
+
});
|
|
1266
|
+
const normalized = this.normalizeRemoteResult(agent, taskId, remoteResult, false);
|
|
1267
|
+
const logLevel = normalized.success ? 'info' : 'error';
|
|
1268
|
+
this.taskManagementService.addTaskLog(taskId, {
|
|
1269
|
+
level: logLevel,
|
|
1270
|
+
message: normalized.success
|
|
1271
|
+
? 'Remote agent execute completed successfully'
|
|
1272
|
+
: `Remote agent execute failed: ${normalized.error || 'Unknown error'}`,
|
|
1273
|
+
});
|
|
1274
|
+
this.taskManagementService.completeTask(taskId, normalized, normalized.success !== false);
|
|
1275
|
+
if (traceTaskId) {
|
|
1276
|
+
if (normalized.success !== false) {
|
|
1277
|
+
this.tracingService?.completeTask(traceTaskId, (0, extract_text_1.extractTextFromContent)(normalized.content), normalized.exitCode);
|
|
1278
|
+
}
|
|
1279
|
+
else {
|
|
1280
|
+
this.tracingService?.failTask(traceTaskId, normalized.error || 'Unknown error', normalized.exitCode);
|
|
1281
|
+
}
|
|
1282
|
+
traceCompleted = true;
|
|
1283
|
+
}
|
|
1284
|
+
return normalized;
|
|
1285
|
+
}
|
|
1286
|
+
catch (error) {
|
|
1287
|
+
const errorMessage = (0, crewx_sdk_1.getErrorMessage)(error);
|
|
1288
|
+
this.taskManagementService.addTaskLog(taskId, {
|
|
1289
|
+
level: 'error',
|
|
1290
|
+
message: `Remote agent execute failed: ${errorMessage}`,
|
|
1291
|
+
});
|
|
1292
|
+
this.taskManagementService.completeTask(taskId, { success: false, error: errorMessage }, false);
|
|
1293
|
+
if (traceTaskId) {
|
|
1294
|
+
this.tracingService?.failTask(traceTaskId, errorMessage);
|
|
1295
|
+
traceCompleted = true;
|
|
1296
|
+
}
|
|
1297
|
+
return {
|
|
1298
|
+
content: [
|
|
1299
|
+
{
|
|
1300
|
+
type: 'text',
|
|
1301
|
+
text: `❌ **Remote agent error**\n\n${errorMessage}`,
|
|
1302
|
+
},
|
|
1303
|
+
],
|
|
1304
|
+
success: false,
|
|
1305
|
+
agent: agentId,
|
|
1306
|
+
provider: 'remote',
|
|
1307
|
+
error: errorMessage,
|
|
1308
|
+
taskId,
|
|
1309
|
+
executionMode: true,
|
|
1310
|
+
readOnly: false,
|
|
1311
|
+
};
|
|
1312
|
+
}
|
|
1313
|
+
}
|
|
1314
|
+
const workingDir = projectPath || agent.workingDirectory || './';
|
|
1315
|
+
const securityKey = this.generateSecurityKey();
|
|
1316
|
+
const contextMessages = messages && messages.length > 0 ? messages : [];
|
|
1317
|
+
const documentsForExecute = {};
|
|
1318
|
+
const docNamesForExecute = this.documentLoaderService.getDocumentNames();
|
|
1319
|
+
for (const docName of docNamesForExecute) {
|
|
1320
|
+
const content = await this.documentLoaderService.getDocumentContent(docName);
|
|
1321
|
+
const toc = await this.documentLoaderService.getDocumentToc(docName);
|
|
1322
|
+
if (content) {
|
|
1323
|
+
documentsForExecute[docName] = { content, toc };
|
|
1324
|
+
}
|
|
1325
|
+
}
|
|
1326
|
+
const templateContext = {
|
|
1327
|
+
user_input: task,
|
|
1328
|
+
messages: contextMessages,
|
|
1329
|
+
agent: {
|
|
1330
|
+
id: agent.id,
|
|
1331
|
+
name: agent.name || agent.id,
|
|
1332
|
+
provider: (Array.isArray(agent.provider) ? agent.provider[0] : agent.provider) || 'claude',
|
|
1333
|
+
model: model || agent.inline?.model,
|
|
1334
|
+
workingDirectory: workingDir,
|
|
1335
|
+
inline: {
|
|
1336
|
+
prompt: agent.inline?.prompt || agent.inline?.system_prompt || agent.systemPrompt || '',
|
|
1337
|
+
},
|
|
1338
|
+
specialties: agent.specialties,
|
|
1339
|
+
capabilities: agent.capabilities,
|
|
1340
|
+
description: agent.description,
|
|
1341
|
+
},
|
|
1342
|
+
documents: documentsForExecute,
|
|
1343
|
+
vars: {
|
|
1344
|
+
security_key: securityKey,
|
|
1345
|
+
},
|
|
1346
|
+
props: {},
|
|
1347
|
+
mode: 'execute',
|
|
1348
|
+
platform: platform,
|
|
1349
|
+
metadata: metadata,
|
|
1350
|
+
env: process.env,
|
|
1351
|
+
tools: this.buildToolsContext(),
|
|
1352
|
+
};
|
|
1353
|
+
let systemPrompt = await this.processAgentSystemPrompt(agent, templateContext);
|
|
1354
|
+
if (process.env.CREWX_APPEND_LEGACY === 'true') {
|
|
1355
|
+
this.logger.debug('[WBS-14] Legacy append mode enabled (execute)', {
|
|
1356
|
+
agentId: agent.id,
|
|
1357
|
+
layoutId: typeof agent.inline?.layout === 'string'
|
|
1358
|
+
? agent.inline?.layout
|
|
1359
|
+
: agent.inline?.layout?.id ?? 'crewx/default',
|
|
1360
|
+
});
|
|
1361
|
+
systemPrompt += `
|
|
1362
|
+
Specialties: ${agent.specialties?.join(', ') || 'General'}
|
|
1363
|
+
Capabilities: ${agent.capabilities?.join(', ') || 'Implementation'}
|
|
1364
|
+
Working Directory: ${workingDir}`;
|
|
1365
|
+
}
|
|
1366
|
+
else if (process.env.CREWX_WBS14_TELEMETRY === 'true') {
|
|
1367
|
+
this.logger.debug('[WBS-14] Metadata delegated to layout (execute mode)', {
|
|
1368
|
+
agentId: agent.id,
|
|
1369
|
+
hasLayout: Boolean(agent.inline?.layout),
|
|
1370
|
+
layoutId: typeof agent.inline?.layout === 'string'
|
|
1371
|
+
? agent.inline?.layout
|
|
1372
|
+
: agent.inline?.layout?.id ?? 'crewx/default',
|
|
1373
|
+
specialtiesCount: agent.specialties?.length ?? 0,
|
|
1374
|
+
capabilitiesCount: agent.capabilities?.length ?? 0,
|
|
1375
|
+
workingDirectory: workingDir,
|
|
1376
|
+
});
|
|
1377
|
+
}
|
|
1378
|
+
const fullPrompt = context
|
|
1379
|
+
? `${systemPrompt}
|
|
1380
|
+
${context}
|
|
1381
|
+
|
|
1382
|
+
Task: ${task}
|
|
1383
|
+
`
|
|
1384
|
+
: `${systemPrompt}
|
|
1385
|
+
|
|
1386
|
+
Task: ${task}
|
|
1387
|
+
`;
|
|
1388
|
+
if (traceTaskId) {
|
|
1389
|
+
this.tracingService?.updateTaskRenderedPrompt(traceTaskId, fullPrompt);
|
|
1390
|
+
}
|
|
1391
|
+
const promptLength = fullPrompt.length;
|
|
1392
|
+
this.taskManagementService.addTaskLog(taskId, {
|
|
1393
|
+
level: 'info',
|
|
1394
|
+
message: `Prompt length: ${promptLength} characters`,
|
|
1395
|
+
});
|
|
1396
|
+
let runtimeResult;
|
|
1397
|
+
let providerResolution;
|
|
1398
|
+
let providerInput;
|
|
1399
|
+
if (args.provider) {
|
|
1400
|
+
providerInput = args.provider;
|
|
1401
|
+
}
|
|
1402
|
+
else if (Array.isArray(agent.provider)) {
|
|
1403
|
+
providerInput = await this.getAvailableProvider(agent.provider);
|
|
1404
|
+
}
|
|
1405
|
+
else if (typeof agent.provider === 'string' && agent.provider.trim().length > 0) {
|
|
1406
|
+
if (agent.provider.startsWith('api/')) {
|
|
1407
|
+
providerInput = agentId;
|
|
1408
|
+
}
|
|
1409
|
+
else {
|
|
1410
|
+
providerInput = agent.provider;
|
|
1411
|
+
}
|
|
1412
|
+
}
|
|
1413
|
+
try {
|
|
1414
|
+
runtimeResult = await this.providerBridgeService.createAgentRuntime({
|
|
1415
|
+
provider: providerInput,
|
|
1416
|
+
defaultAgentId: agentId,
|
|
1417
|
+
validAgents: agents.map(a => a.id),
|
|
1418
|
+
enableCallStack: true,
|
|
1419
|
+
});
|
|
1420
|
+
providerResolution = runtimeResult.resolution;
|
|
1421
|
+
}
|
|
1422
|
+
catch (error) {
|
|
1423
|
+
const errorMsg = error instanceof Error ? error.message : 'Unknown provider error';
|
|
1424
|
+
this.taskManagementService.addTaskLog(taskId, {
|
|
1425
|
+
level: 'error',
|
|
1426
|
+
message: `Provider resolution failed: ${errorMsg}`,
|
|
1427
|
+
});
|
|
1428
|
+
this.taskManagementService.completeTask(taskId, { success: false, error: errorMsg }, false);
|
|
1429
|
+
if (traceTaskId) {
|
|
1430
|
+
this.tracingService?.failTask(traceTaskId, errorMsg);
|
|
1431
|
+
traceCompleted = true;
|
|
1432
|
+
}
|
|
1433
|
+
return {
|
|
1434
|
+
content: [
|
|
1435
|
+
{
|
|
1436
|
+
type: 'text',
|
|
1437
|
+
text: `❌ **Provider Error**\n\n${errorMsg}\n\nAvailable providers: ${this.providerBridgeService.listAvailableProviders().join(', ')}`,
|
|
1438
|
+
},
|
|
1439
|
+
],
|
|
1440
|
+
success: false,
|
|
1441
|
+
agent: agentId,
|
|
1442
|
+
provider: 'none',
|
|
1443
|
+
error: errorMsg,
|
|
1444
|
+
taskId,
|
|
1445
|
+
readOnlyMode: false,
|
|
1446
|
+
readOnly: false,
|
|
1447
|
+
};
|
|
1448
|
+
}
|
|
1449
|
+
const resolvedProviderName = providerResolution.provider.name;
|
|
1450
|
+
if (args.provider) {
|
|
1451
|
+
this.taskManagementService.addTaskLog(taskId, {
|
|
1452
|
+
level: 'info',
|
|
1453
|
+
message: `Using CLI-specified provider: ${args.provider} (resolved to ${resolvedProviderName})`
|
|
1454
|
+
});
|
|
1455
|
+
}
|
|
1456
|
+
else if (providerInput) {
|
|
1457
|
+
this.taskManagementService.addTaskLog(taskId, {
|
|
1458
|
+
level: 'info',
|
|
1459
|
+
message: `Agent provider resolved to ${resolvedProviderName} (input: ${providerInput})`
|
|
1460
|
+
});
|
|
1461
|
+
}
|
|
1462
|
+
else {
|
|
1463
|
+
this.taskManagementService.addTaskLog(taskId, {
|
|
1464
|
+
level: 'info',
|
|
1465
|
+
message: `Using ProviderBridge fallback provider: ${resolvedProviderName}`,
|
|
1466
|
+
});
|
|
1467
|
+
}
|
|
1468
|
+
const agentOptions = this.getOptionsForAgent(agent, 'execute', resolvedProviderName);
|
|
1469
|
+
const modelToUse = model || agent.inline?.model || providerResolution.defaultModel;
|
|
1470
|
+
const structuredPayload = await this.buildStructuredPayload({
|
|
1471
|
+
agentId,
|
|
1472
|
+
provider: resolvedProviderName,
|
|
1473
|
+
mode: 'execute',
|
|
1474
|
+
prompt: fullPrompt,
|
|
1475
|
+
context,
|
|
1476
|
+
messages,
|
|
1477
|
+
platform: platform || 'cli',
|
|
1478
|
+
model: modelToUse,
|
|
1479
|
+
platformMetadata: metadata,
|
|
1480
|
+
});
|
|
1481
|
+
const runtimeMessages = this.toConversationMessages(messages);
|
|
1482
|
+
let agentResult;
|
|
1483
|
+
let pidRecorded = false;
|
|
1484
|
+
const handleProcessStart = (pid) => {
|
|
1485
|
+
if (!traceTaskId) {
|
|
1486
|
+
return;
|
|
1487
|
+
}
|
|
1488
|
+
const updated = this.tracingService?.updateTaskPid(traceTaskId, pid) ?? false;
|
|
1489
|
+
if (updated) {
|
|
1490
|
+
pidRecorded = true;
|
|
1491
|
+
}
|
|
1492
|
+
};
|
|
1493
|
+
try {
|
|
1494
|
+
const originalLog = console.log;
|
|
1495
|
+
console.log = (...args) => {
|
|
1496
|
+
const message = args.map(arg => typeof arg === 'object' ? JSON.stringify(arg) : String(arg)).join(' ');
|
|
1497
|
+
if (message.includes('[INFO]')) {
|
|
1498
|
+
this.taskManagementService.addTaskLog(taskId, {
|
|
1499
|
+
level: 'info',
|
|
1500
|
+
message: message.replace('[INFO] ', ''),
|
|
1501
|
+
});
|
|
1502
|
+
}
|
|
1503
|
+
originalLog.apply(console, args);
|
|
1504
|
+
};
|
|
1505
|
+
const processedEnv = await this.processAgentEnv(agent.env, agent);
|
|
1506
|
+
try {
|
|
1507
|
+
agentResult = await runtimeResult.runtime.agent.execute({
|
|
1508
|
+
agentId,
|
|
1509
|
+
prompt: fullPrompt,
|
|
1510
|
+
context,
|
|
1511
|
+
messages: runtimeMessages,
|
|
1512
|
+
model: modelToUse,
|
|
1513
|
+
options: {
|
|
1514
|
+
workingDirectory: workingDir,
|
|
1515
|
+
timeout: this.timeoutConfig.parallel,
|
|
1516
|
+
additionalArgs: agentOptions,
|
|
1517
|
+
taskId,
|
|
1518
|
+
pipedContext: structuredPayload,
|
|
1519
|
+
securityKey,
|
|
1520
|
+
env: processedEnv,
|
|
1521
|
+
runtime: agent.runtime,
|
|
1522
|
+
traceId,
|
|
1523
|
+
onProcessStart: handleProcessStart,
|
|
1524
|
+
},
|
|
1525
|
+
});
|
|
1526
|
+
}
|
|
1527
|
+
finally {
|
|
1528
|
+
console.log = originalLog;
|
|
1529
|
+
}
|
|
1530
|
+
}
|
|
1531
|
+
catch (error) {
|
|
1532
|
+
const errorMsg = error instanceof Error ? error.message : 'Agent runtime execution failed';
|
|
1533
|
+
this.taskManagementService.addTaskLog(taskId, {
|
|
1534
|
+
level: 'error',
|
|
1535
|
+
message: `Agent runtime execution failed: ${errorMsg}`,
|
|
1536
|
+
});
|
|
1537
|
+
this.taskManagementService.completeTask(taskId, { success: false, error: errorMsg }, false);
|
|
1538
|
+
if (traceTaskId) {
|
|
1539
|
+
this.tracingService?.failTask(traceTaskId, errorMsg);
|
|
1540
|
+
traceCompleted = true;
|
|
1541
|
+
}
|
|
1542
|
+
return {
|
|
1543
|
+
content: [
|
|
1544
|
+
{
|
|
1545
|
+
type: 'text',
|
|
1546
|
+
text: `❌ **Provider Error**\n\n${errorMsg}\n\nAvailable providers: ${this.providerBridgeService.listAvailableProviders().join(', ')}`,
|
|
1547
|
+
},
|
|
1548
|
+
],
|
|
1549
|
+
success: false,
|
|
1550
|
+
agent: agentId,
|
|
1551
|
+
provider: resolvedProviderName,
|
|
1552
|
+
error: errorMsg,
|
|
1553
|
+
taskId,
|
|
1554
|
+
readOnlyMode: false,
|
|
1555
|
+
readOnly: false,
|
|
1556
|
+
};
|
|
1557
|
+
}
|
|
1558
|
+
const response = {
|
|
1559
|
+
success: agentResult.success,
|
|
1560
|
+
content: agentResult.content,
|
|
1561
|
+
provider: agentResult.metadata?.provider ?? resolvedProviderName,
|
|
1562
|
+
taskId: agentResult.metadata?.taskId ?? taskId,
|
|
1563
|
+
error: agentResult.metadata?.error,
|
|
1564
|
+
pid: agentResult.metadata?.pid,
|
|
1565
|
+
command: agentResult.metadata?.command,
|
|
1566
|
+
exitCode: agentResult.metadata?.exitCode,
|
|
1567
|
+
durationMs: agentResult.metadata?.durationMs,
|
|
1568
|
+
timeToFirstOutputMs: agentResult.metadata?.timeToFirstOutputMs,
|
|
1569
|
+
};
|
|
1570
|
+
if (traceTaskId && response.pid && !pidRecorded) {
|
|
1571
|
+
this.tracingService?.updateTaskPid(traceTaskId, response.pid);
|
|
1572
|
+
}
|
|
1573
|
+
if (traceTaskId && response.command) {
|
|
1574
|
+
this.tracingService?.updateTaskCodingAgentCommand(traceTaskId, response.command);
|
|
1575
|
+
}
|
|
1576
|
+
if (response.command) {
|
|
1577
|
+
this.taskManagementService.addTaskLog(taskId, {
|
|
1578
|
+
level: 'info',
|
|
1579
|
+
message: `Coding agent command: ${response.command}`,
|
|
1580
|
+
});
|
|
1581
|
+
}
|
|
1582
|
+
if (response.pid !== undefined) {
|
|
1583
|
+
this.taskManagementService.addTaskLog(taskId, {
|
|
1584
|
+
level: 'info',
|
|
1585
|
+
message: `PID: ${response.pid ?? 'unknown'}`,
|
|
1586
|
+
});
|
|
1587
|
+
}
|
|
1588
|
+
if (response.exitCode !== undefined) {
|
|
1589
|
+
this.taskManagementService.addTaskLog(taskId, {
|
|
1590
|
+
level: 'info',
|
|
1591
|
+
message: `Exit code: ${response.exitCode ?? 'unknown'}`,
|
|
1592
|
+
});
|
|
1593
|
+
}
|
|
1594
|
+
if (response.durationMs !== undefined) {
|
|
1595
|
+
this.taskManagementService.addTaskLog(taskId, {
|
|
1596
|
+
level: 'info',
|
|
1597
|
+
message: `Duration: ${response.durationMs}ms`,
|
|
1598
|
+
});
|
|
1599
|
+
}
|
|
1600
|
+
if (response.timeToFirstOutputMs !== undefined) {
|
|
1601
|
+
const firstResponseText = response.timeToFirstOutputMs === null
|
|
1602
|
+
? 'unknown'
|
|
1603
|
+
: `${response.timeToFirstOutputMs}ms`;
|
|
1604
|
+
this.taskManagementService.addTaskLog(taskId, {
|
|
1605
|
+
level: 'info',
|
|
1606
|
+
message: `First response: ${firstResponseText}`,
|
|
1607
|
+
});
|
|
1608
|
+
}
|
|
1609
|
+
this.taskManagementService.addTaskLog(taskId, { level: 'info', message: `Execution completed. Success: ${response.success}` });
|
|
1610
|
+
this.taskManagementService.completeTask(taskId, response, response.success);
|
|
1611
|
+
if (traceTaskId) {
|
|
1612
|
+
if (response.success) {
|
|
1613
|
+
this.tracingService?.completeTask(traceTaskId, response.content, response.exitCode);
|
|
1614
|
+
}
|
|
1615
|
+
else {
|
|
1616
|
+
this.tracingService?.failTask(traceTaskId, response.error || 'Unknown error', response.exitCode);
|
|
1617
|
+
}
|
|
1618
|
+
traceCompleted = true;
|
|
1619
|
+
}
|
|
1620
|
+
const responseText = response.success ? response.content : `❌ Execution Failed: ${response.error}`;
|
|
1621
|
+
return {
|
|
1622
|
+
content: [
|
|
1623
|
+
{
|
|
1624
|
+
type: 'text',
|
|
1625
|
+
text: responseText
|
|
1626
|
+
}
|
|
1627
|
+
],
|
|
1628
|
+
success: response.success,
|
|
1629
|
+
taskId: taskId,
|
|
1630
|
+
agent: agentId,
|
|
1631
|
+
provider: response.provider,
|
|
1632
|
+
implementation: response.content,
|
|
1633
|
+
error: response.error,
|
|
1634
|
+
recommendations: []
|
|
1635
|
+
};
|
|
1636
|
+
}
|
|
1637
|
+
catch (error) {
|
|
1638
|
+
const errorMessage = (0, crewx_sdk_1.getErrorMessage)(error);
|
|
1639
|
+
if (traceTaskId) {
|
|
1640
|
+
this.tracingService?.failTask(traceTaskId, errorMessage);
|
|
1641
|
+
traceCompleted = true;
|
|
1642
|
+
}
|
|
1643
|
+
if (taskId) {
|
|
1644
|
+
this.taskManagementService.addTaskLog(taskId, { level: 'error', message: `Execution failed: ${errorMessage}` });
|
|
1645
|
+
this.taskManagementService.completeTask(taskId, { error: errorMessage }, false);
|
|
1646
|
+
this.logger.error(`[${taskId}] Agent execution failed for ${agentId}:`, errorMessage);
|
|
1647
|
+
}
|
|
1648
|
+
else {
|
|
1649
|
+
this.logger.error(`Agent execution failed for ${agentId} (no task ID):`, errorMessage);
|
|
1650
|
+
}
|
|
1651
|
+
return {
|
|
1652
|
+
content: [
|
|
1653
|
+
{
|
|
1654
|
+
type: 'text',
|
|
1655
|
+
text: `❌ Execution Failed: ${errorMessage}`
|
|
1656
|
+
}
|
|
1657
|
+
],
|
|
1658
|
+
success: false,
|
|
1659
|
+
taskId: taskId,
|
|
1660
|
+
agent: agentId,
|
|
1661
|
+
provider: 'unknown',
|
|
1662
|
+
implementation: null,
|
|
1663
|
+
error: errorMessage,
|
|
1664
|
+
recommendations: []
|
|
1665
|
+
};
|
|
1666
|
+
}
|
|
1667
|
+
finally {
|
|
1668
|
+
if (!traceCompleted && traceTaskId) {
|
|
1669
|
+
this.tracingService?.failTask(traceTaskId, 'unexpected exit');
|
|
1670
|
+
}
|
|
1671
|
+
}
|
|
1672
|
+
}
|
|
1673
|
+
normalizeRemoteResult(agent, taskId, remoteResult, readOnly) {
|
|
1674
|
+
const normalizedAgentId = remoteResult?.agent ?? agent.remote?.agentId ?? agent.id;
|
|
1675
|
+
const provider = remoteResult?.provider ?? 'remote';
|
|
1676
|
+
let content = remoteResult?.content;
|
|
1677
|
+
if (!Array.isArray(content) || content.length === 0) {
|
|
1678
|
+
const fallback = remoteResult?.response ??
|
|
1679
|
+
remoteResult?.implementation ??
|
|
1680
|
+
remoteResult?.message ??
|
|
1681
|
+
remoteResult?.output;
|
|
1682
|
+
const text = typeof fallback === 'string'
|
|
1683
|
+
? fallback
|
|
1684
|
+
: JSON.stringify(fallback ?? remoteResult, null, 2);
|
|
1685
|
+
content = [
|
|
1686
|
+
{
|
|
1687
|
+
type: 'text',
|
|
1688
|
+
text,
|
|
1689
|
+
},
|
|
1690
|
+
];
|
|
1691
|
+
}
|
|
1692
|
+
return {
|
|
1693
|
+
...remoteResult,
|
|
1694
|
+
content,
|
|
1695
|
+
agent: normalizedAgentId,
|
|
1696
|
+
provider,
|
|
1697
|
+
taskId: remoteResult?.taskId ?? taskId,
|
|
1698
|
+
success: remoteResult?.success !== false,
|
|
1699
|
+
readOnlyMode: readOnly,
|
|
1700
|
+
readOnly,
|
|
1701
|
+
};
|
|
1702
|
+
}
|
|
1703
|
+
toConversationMessages(messages) {
|
|
1704
|
+
if (!messages || messages.length === 0) {
|
|
1705
|
+
return [];
|
|
1706
|
+
}
|
|
1707
|
+
return messages.map((message, index) => {
|
|
1708
|
+
const metadata = message.metadata ?? {};
|
|
1709
|
+
const rawTimestamp = metadata.timestamp;
|
|
1710
|
+
let timestamp;
|
|
1711
|
+
if (rawTimestamp instanceof Date) {
|
|
1712
|
+
timestamp = rawTimestamp;
|
|
1713
|
+
}
|
|
1714
|
+
else if (typeof rawTimestamp === 'number') {
|
|
1715
|
+
timestamp = new Date(rawTimestamp);
|
|
1716
|
+
}
|
|
1717
|
+
else if (typeof rawTimestamp === 'string') {
|
|
1718
|
+
const parsed = new Date(rawTimestamp);
|
|
1719
|
+
timestamp = Number.isNaN(parsed.getTime()) ? new Date() : parsed;
|
|
1720
|
+
}
|
|
1721
|
+
else {
|
|
1722
|
+
timestamp = new Date();
|
|
1723
|
+
}
|
|
1724
|
+
return {
|
|
1725
|
+
id: typeof metadata.id === 'string' ? metadata.id : `cli-msg-${index}`,
|
|
1726
|
+
userId: typeof metadata.userId === 'string'
|
|
1727
|
+
? metadata.userId
|
|
1728
|
+
: message.isAssistant
|
|
1729
|
+
? 'assistant'
|
|
1730
|
+
: 'user',
|
|
1731
|
+
text: message.text,
|
|
1732
|
+
timestamp,
|
|
1733
|
+
isAssistant: message.isAssistant,
|
|
1734
|
+
metadata: metadata,
|
|
1735
|
+
files: message.files,
|
|
1736
|
+
};
|
|
1737
|
+
});
|
|
1738
|
+
}
|
|
1739
|
+
getOptionsForAgent(agent, mode, provider) {
|
|
1740
|
+
try {
|
|
1741
|
+
if (agent.options && typeof agent.options === 'object' && !Array.isArray(agent.options)) {
|
|
1742
|
+
const modeOptions = agent.options[mode];
|
|
1743
|
+
if (modeOptions && typeof modeOptions === 'object' && !Array.isArray(modeOptions)) {
|
|
1744
|
+
if (provider) {
|
|
1745
|
+
const simpleProviderName = provider.includes('/') ? provider.split('/').pop() : provider;
|
|
1746
|
+
if (simpleProviderName && modeOptions[simpleProviderName]) {
|
|
1747
|
+
return modeOptions[simpleProviderName];
|
|
1748
|
+
}
|
|
1749
|
+
if (modeOptions[provider]) {
|
|
1750
|
+
return modeOptions[provider];
|
|
1751
|
+
}
|
|
1752
|
+
}
|
|
1753
|
+
if (modeOptions['default']) {
|
|
1754
|
+
return modeOptions['default'];
|
|
1755
|
+
}
|
|
1756
|
+
return [];
|
|
1757
|
+
}
|
|
1758
|
+
return modeOptions || [];
|
|
1759
|
+
}
|
|
1760
|
+
if (agent.options && Array.isArray(agent.options)) {
|
|
1761
|
+
return agent.options;
|
|
1762
|
+
}
|
|
1763
|
+
return [];
|
|
1764
|
+
}
|
|
1765
|
+
catch (error) {
|
|
1766
|
+
this.logger.warn(`Failed to get options for agent ${agent.id}: ${error}`);
|
|
1767
|
+
return [];
|
|
1768
|
+
}
|
|
1769
|
+
}
|
|
1770
|
+
async queryAgentParallel(args) {
|
|
1771
|
+
try {
|
|
1772
|
+
const { queries } = args || {};
|
|
1773
|
+
this.logger.log(`Starting parallel agent queries (${queries?.length || 0} queries)`);
|
|
1774
|
+
if (!queries || queries.length === 0) {
|
|
1775
|
+
return {
|
|
1776
|
+
content: [
|
|
1777
|
+
{
|
|
1778
|
+
type: 'text',
|
|
1779
|
+
text: `❌ **No Queries Provided**
|
|
1780
|
+
|
|
1781
|
+
Please provide at least one query in the queries array.
|
|
1782
|
+
|
|
1783
|
+
**Example:**
|
|
1784
|
+
\`\`\`json
|
|
1785
|
+
{
|
|
1786
|
+
"queries": [
|
|
1787
|
+
{
|
|
1788
|
+
"agentId": "gmail_mcp_developer",
|
|
1789
|
+
"query": "Analyze the README"
|
|
1790
|
+
},
|
|
1791
|
+
{
|
|
1792
|
+
"agentId": "frontend_developer",
|
|
1793
|
+
"query": "Explain the component structure"
|
|
1794
|
+
}
|
|
1795
|
+
]
|
|
1796
|
+
}
|
|
1797
|
+
\`\`\``
|
|
1798
|
+
}
|
|
1799
|
+
],
|
|
1800
|
+
success: false,
|
|
1801
|
+
error: 'No queries provided',
|
|
1802
|
+
results: []
|
|
1803
|
+
};
|
|
1804
|
+
}
|
|
1805
|
+
queries.forEach((q, index) => {
|
|
1806
|
+
const queryPreview = q.query ? q.query.substring(0, 50) : '(no query)';
|
|
1807
|
+
this.logger.log(`Query ${index + 1}: ${q.agentId || '(no agent)'} -> "${queryPreview}..."`);
|
|
1808
|
+
});
|
|
1809
|
+
const startTime = Date.now();
|
|
1810
|
+
const queryPromises = queries.map(async (q, index) => {
|
|
1811
|
+
const queryStart = Date.now();
|
|
1812
|
+
try {
|
|
1813
|
+
const result = await this.queryAgent({
|
|
1814
|
+
agentId: q.agentId,
|
|
1815
|
+
query: q.query,
|
|
1816
|
+
context: q.context,
|
|
1817
|
+
model: q.model,
|
|
1818
|
+
messages: q.messages,
|
|
1819
|
+
platform: q.platform
|
|
1820
|
+
});
|
|
1821
|
+
const duration = Date.now() - queryStart;
|
|
1822
|
+
return {
|
|
1823
|
+
index: index + 1,
|
|
1824
|
+
agentId: q.agentId,
|
|
1825
|
+
query: q.query,
|
|
1826
|
+
success: result.success !== false,
|
|
1827
|
+
response: result.response || result.content?.[0]?.text,
|
|
1828
|
+
provider: result.provider,
|
|
1829
|
+
duration,
|
|
1830
|
+
taskId: result.taskId
|
|
1831
|
+
};
|
|
1832
|
+
}
|
|
1833
|
+
catch (error) {
|
|
1834
|
+
const duration = Date.now() - queryStart;
|
|
1835
|
+
return {
|
|
1836
|
+
index: index + 1,
|
|
1837
|
+
agentId: q.agentId,
|
|
1838
|
+
query: q.query,
|
|
1839
|
+
success: false,
|
|
1840
|
+
error: error.message,
|
|
1841
|
+
duration
|
|
1842
|
+
};
|
|
1843
|
+
}
|
|
1844
|
+
});
|
|
1845
|
+
const results = await Promise.all(queryPromises);
|
|
1846
|
+
const totalDuration = Date.now() - startTime;
|
|
1847
|
+
const successCount = results.filter(r => r.success).length;
|
|
1848
|
+
const failureCount = results.length - successCount;
|
|
1849
|
+
const summary = {
|
|
1850
|
+
total: results.length,
|
|
1851
|
+
successful: successCount,
|
|
1852
|
+
failed: failureCount,
|
|
1853
|
+
totalDuration,
|
|
1854
|
+
averageDuration: results.reduce((sum, r) => sum + r.duration, 0) / results.length
|
|
1855
|
+
};
|
|
1856
|
+
this.logger.log(`Parallel queries completed: ${successCount} success, ${failureCount} failed, ${totalDuration}ms total`);
|
|
1857
|
+
const enhancedResults = results;
|
|
1858
|
+
const formattedResult = this.resultFormatterService.formatParallelResult(enhancedResults, {
|
|
1859
|
+
total: summary.total,
|
|
1860
|
+
success: summary.successful,
|
|
1861
|
+
failed: summary.failed,
|
|
1862
|
+
totalDuration: summary.totalDuration,
|
|
1863
|
+
averageDuration: summary.averageDuration,
|
|
1864
|
+
fastest: Math.min(...results.map(r => r.duration)),
|
|
1865
|
+
slowest: Math.max(...results.map(r => r.duration)),
|
|
1866
|
+
timeSaved: Math.max(0, results.reduce((sum, r) => sum + r.duration, 0) - summary.totalDuration)
|
|
1867
|
+
}, true);
|
|
1868
|
+
return {
|
|
1869
|
+
content: [
|
|
1870
|
+
{
|
|
1871
|
+
type: 'text',
|
|
1872
|
+
text: formattedResult.mcp
|
|
1873
|
+
}
|
|
1874
|
+
],
|
|
1875
|
+
success: true,
|
|
1876
|
+
summary: {
|
|
1877
|
+
totalQueries: summary.total,
|
|
1878
|
+
successful: summary.successful,
|
|
1879
|
+
failed: summary.failed,
|
|
1880
|
+
totalDuration: summary.totalDuration,
|
|
1881
|
+
averageDuration: summary.averageDuration
|
|
1882
|
+
},
|
|
1883
|
+
results: enhancedResults,
|
|
1884
|
+
performance: {
|
|
1885
|
+
fastestQuery: Math.min(...results.map(r => r.duration)),
|
|
1886
|
+
slowestQuery: Math.max(...results.map(r => r.duration)),
|
|
1887
|
+
timeSaved: Math.max(0, results.reduce((sum, r) => sum + r.duration, 0) - summary.totalDuration)
|
|
1888
|
+
},
|
|
1889
|
+
readOnlyMode: true
|
|
1890
|
+
};
|
|
1891
|
+
}
|
|
1892
|
+
catch (error) {
|
|
1893
|
+
const errorMessage = (0, crewx_sdk_1.getErrorMessage)(error);
|
|
1894
|
+
this.logger.error('Parallel agent queries failed:', errorMessage);
|
|
1895
|
+
return {
|
|
1896
|
+
content: [
|
|
1897
|
+
{
|
|
1898
|
+
type: 'text',
|
|
1899
|
+
text: `❌ **Parallel Agent Queries Failed**
|
|
1900
|
+
|
|
1901
|
+
**Error:** ${errorMessage}
|
|
1902
|
+
|
|
1903
|
+
**Total Queries:** ${args.queries?.length || 0}
|
|
1904
|
+
|
|
1905
|
+
Read-Only Mode: No files were modified.`
|
|
1906
|
+
}
|
|
1907
|
+
],
|
|
1908
|
+
success: false,
|
|
1909
|
+
error: errorMessage,
|
|
1910
|
+
results: [],
|
|
1911
|
+
readOnlyMode: true
|
|
1912
|
+
};
|
|
1913
|
+
}
|
|
1914
|
+
}
|
|
1915
|
+
async executeAgentParallel(args) {
|
|
1916
|
+
try {
|
|
1917
|
+
const { tasks } = args || {};
|
|
1918
|
+
this.logger.log(`Starting parallel agent execution (${tasks?.length || 0} tasks)`);
|
|
1919
|
+
if (!tasks || tasks.length === 0) {
|
|
1920
|
+
return {
|
|
1921
|
+
content: [
|
|
1922
|
+
{
|
|
1923
|
+
type: 'text',
|
|
1924
|
+
text: `❌ **No Tasks Provided**
|
|
1925
|
+
|
|
1926
|
+
Please provide at least one task in the tasks array.
|
|
1927
|
+
|
|
1928
|
+
**Example:**
|
|
1929
|
+
\`\`\`json
|
|
1930
|
+
{
|
|
1931
|
+
"tasks": [
|
|
1932
|
+
{
|
|
1933
|
+
"task": "Create a utility function for handling timeouts"
|
|
1934
|
+
},
|
|
1935
|
+
{
|
|
1936
|
+
"agentId": "crewx_developer_claude",
|
|
1937
|
+
"task": "Write unit tests for the new utility function"
|
|
1938
|
+
},
|
|
1939
|
+
{
|
|
1940
|
+
"agentId": "crewx_developer_gemini",
|
|
1941
|
+
"task": "Review the implementation for edge cases"
|
|
1942
|
+
}
|
|
1943
|
+
]
|
|
1944
|
+
}
|
|
1945
|
+
\`\`\``
|
|
1946
|
+
}
|
|
1947
|
+
],
|
|
1948
|
+
success: false,
|
|
1949
|
+
error: 'No tasks provided',
|
|
1950
|
+
results: []
|
|
1951
|
+
};
|
|
1952
|
+
}
|
|
1953
|
+
tasks.forEach((t, index) => {
|
|
1954
|
+
const taskPreview = t.task ? t.task.substring(0, 50) : '(no task)';
|
|
1955
|
+
this.logger.log(`Task ${index + 1}: ${t.agentId || '(no agent)'} -> "${taskPreview}..."`);
|
|
1956
|
+
});
|
|
1957
|
+
const startTime = Date.now();
|
|
1958
|
+
const results = await Promise.all(tasks.map(async (taskItem, index) => {
|
|
1959
|
+
const taskStartTime = Date.now();
|
|
1960
|
+
try {
|
|
1961
|
+
const result = await this.executeAgent({
|
|
1962
|
+
agentId: taskItem.agentId,
|
|
1963
|
+
task: taskItem.task,
|
|
1964
|
+
projectPath: taskItem.projectPath,
|
|
1965
|
+
context: taskItem.context,
|
|
1966
|
+
});
|
|
1967
|
+
const taskDuration = Date.now() - taskStartTime;
|
|
1968
|
+
return {
|
|
1969
|
+
index: index + 1,
|
|
1970
|
+
agentId: taskItem.agentId,
|
|
1971
|
+
task: taskItem.task,
|
|
1972
|
+
success: result.success,
|
|
1973
|
+
implementation: result.implementation || result.error,
|
|
1974
|
+
provider: result.provider,
|
|
1975
|
+
duration: taskDuration,
|
|
1976
|
+
error: result.error,
|
|
1977
|
+
context: taskItem.context,
|
|
1978
|
+
workingDirectory: taskItem.projectPath || `Default for ${taskItem.agentId}`,
|
|
1979
|
+
recommendations: result.recommendations || [],
|
|
1980
|
+
taskId: result.taskId
|
|
1981
|
+
};
|
|
1982
|
+
}
|
|
1983
|
+
catch (error) {
|
|
1984
|
+
const taskDuration = Date.now() - taskStartTime;
|
|
1985
|
+
return {
|
|
1986
|
+
index: index + 1,
|
|
1987
|
+
agentId: taskItem.agentId,
|
|
1988
|
+
task: taskItem.task,
|
|
1989
|
+
success: false,
|
|
1990
|
+
implementation: null,
|
|
1991
|
+
provider: 'unknown',
|
|
1992
|
+
duration: taskDuration,
|
|
1993
|
+
error: error.message || 'Unknown error occurred',
|
|
1994
|
+
context: taskItem.context,
|
|
1995
|
+
workingDirectory: taskItem.projectPath || `Default for ${taskItem.agentId}`,
|
|
1996
|
+
recommendations: [],
|
|
1997
|
+
taskId: null
|
|
1998
|
+
};
|
|
1999
|
+
}
|
|
2000
|
+
}));
|
|
2001
|
+
const totalDuration = Date.now() - startTime;
|
|
2002
|
+
const successCount = results.filter(r => r.success).length;
|
|
2003
|
+
const failureCount = results.length - successCount;
|
|
2004
|
+
this.logger.log(`Parallel execution completed: ${successCount} success, ${failureCount} failed, ${totalDuration}ms total`);
|
|
2005
|
+
const responseText = `⚡ **Parallel Agent Execution Results**
|
|
2006
|
+
|
|
2007
|
+
**Summary:**
|
|
2008
|
+
- Total Tasks: ${results.length}
|
|
2009
|
+
- Successful: ${successCount}
|
|
2010
|
+
- Failed: ${failureCount}
|
|
2011
|
+
- Total Duration: ${totalDuration}ms
|
|
2012
|
+
- Average Duration: ${Math.round(totalDuration / results.length)}ms per task
|
|
2013
|
+
|
|
2014
|
+
**Individual Results:**
|
|
2015
|
+
|
|
2016
|
+
${results.map(result => `---
|
|
2017
|
+
**${result.index}. Agent: ${result.agentId}** (${result.provider}) - ${result.duration}ms
|
|
2018
|
+
**Task:** ${result.task}
|
|
2019
|
+
**Status:** ${result.success ? '✅ Success' : '❌ Failed'}
|
|
2020
|
+
**Working Directory:** ${result.workingDirectory}
|
|
2021
|
+
${result.context ? `**Context:** ${result.context}\n` : ''}
|
|
2022
|
+
**Implementation:**
|
|
2023
|
+
${result.success ? result.implementation : `Error: ${result.error}`}
|
|
2024
|
+
|
|
2025
|
+
${result.recommendations.length > 0 ? `**Recommendations:**
|
|
2026
|
+
${result.recommendations.map((recommendation) => `• ${recommendation}`).join('\n')}` : ''}
|
|
2027
|
+
`).join('\n')}
|
|
2028
|
+
|
|
2029
|
+
**Performance Insights:**
|
|
2030
|
+
- Fastest Task: ${Math.min(...results.map(r => r.duration))}ms
|
|
2031
|
+
- Slowest Task: ${Math.max(...results.map(r => r.duration))}ms
|
|
2032
|
+
- Parallel processing saved approximately ${Math.max(0, results.reduce((sum, r) => sum + r.duration, 0) - totalDuration)}ms compared to sequential execution
|
|
2033
|
+
|
|
2034
|
+
**⚠️ Important Notes:**
|
|
2035
|
+
- All tasks were executed in IMPLEMENTATION MODE with potential file modifications
|
|
2036
|
+
- Review all provided implementations before applying changes
|
|
2037
|
+
- Test in development environment first
|
|
2038
|
+
- Consider backing up files before making modifications`;
|
|
2039
|
+
return {
|
|
2040
|
+
content: [
|
|
2041
|
+
{
|
|
2042
|
+
type: 'text',
|
|
2043
|
+
text: responseText
|
|
2044
|
+
}
|
|
2045
|
+
],
|
|
2046
|
+
success: true,
|
|
2047
|
+
summary: {
|
|
2048
|
+
totalTasks: results.length,
|
|
2049
|
+
successful: successCount,
|
|
2050
|
+
failed: failureCount,
|
|
2051
|
+
totalDuration,
|
|
2052
|
+
averageDuration: Math.round(totalDuration / results.length)
|
|
2053
|
+
},
|
|
2054
|
+
results: results,
|
|
2055
|
+
performance: {
|
|
2056
|
+
fastestTask: Math.min(...results.map(r => r.duration)),
|
|
2057
|
+
slowestTask: Math.max(...results.map(r => r.duration)),
|
|
2058
|
+
timeSaved: Math.max(0, results.reduce((sum, r) => sum + r.duration, 0) - totalDuration)
|
|
2059
|
+
},
|
|
2060
|
+
executionMode: true
|
|
2061
|
+
};
|
|
2062
|
+
}
|
|
2063
|
+
catch (error) {
|
|
2064
|
+
const errorMessage = (0, crewx_sdk_1.getErrorMessage)(error);
|
|
2065
|
+
this.logger.error('Parallel agent execution failed:', errorMessage);
|
|
2066
|
+
return {
|
|
2067
|
+
content: [
|
|
2068
|
+
{
|
|
2069
|
+
type: 'text',
|
|
2070
|
+
text: `❌ **Parallel Agent Execution Failed**
|
|
2071
|
+
|
|
2072
|
+
**Error:** ${errorMessage}
|
|
2073
|
+
|
|
2074
|
+
**Total Tasks:** ${args.tasks?.length || 0}
|
|
2075
|
+
|
|
2076
|
+
Execution Mode: Implementation guidance could not be provided.`
|
|
2077
|
+
}
|
|
2078
|
+
],
|
|
2079
|
+
success: false,
|
|
2080
|
+
error: errorMessage,
|
|
2081
|
+
results: [],
|
|
2082
|
+
executionMode: true
|
|
2083
|
+
};
|
|
2084
|
+
}
|
|
2085
|
+
}
|
|
2086
|
+
async clearAllLogs() {
|
|
2087
|
+
try {
|
|
2088
|
+
const logsDir = path.join(process.cwd(), '.crewx', 'logs');
|
|
2089
|
+
if (!fs.existsSync(logsDir)) {
|
|
2090
|
+
return {
|
|
2091
|
+
content: [
|
|
2092
|
+
{
|
|
2093
|
+
type: 'text',
|
|
2094
|
+
text: `📁 **Log Directory Status**
|
|
2095
|
+
|
|
2096
|
+
❌ **No logs directory found**
|
|
2097
|
+
|
|
2098
|
+
The logs directory \`.crewx/logs\` does not exist. Nothing to clean.
|
|
2099
|
+
|
|
2100
|
+
**Path checked:** \`${logsDir}\`
|
|
2101
|
+
`
|
|
2102
|
+
}
|
|
2103
|
+
],
|
|
2104
|
+
success: true,
|
|
2105
|
+
message: 'No logs directory found',
|
|
2106
|
+
path: logsDir
|
|
2107
|
+
};
|
|
2108
|
+
}
|
|
2109
|
+
const files = fs.readdirSync(logsDir);
|
|
2110
|
+
const logFiles = files.filter(file => file.endsWith('.log'));
|
|
2111
|
+
if (logFiles.length === 0) {
|
|
2112
|
+
return {
|
|
2113
|
+
content: [
|
|
2114
|
+
{
|
|
2115
|
+
type: 'text',
|
|
2116
|
+
text: `📁 **Log Directory Status**
|
|
2117
|
+
|
|
2118
|
+
✅ **Already clean**
|
|
2119
|
+
|
|
2120
|
+
The logs directory exists but contains no log files to clean.
|
|
2121
|
+
|
|
2122
|
+
**Directory:** \`${logsDir}\`
|
|
2123
|
+
**Total files:** ${files.length}
|
|
2124
|
+
**Log files:** 0
|
|
2125
|
+
`
|
|
2126
|
+
}
|
|
2127
|
+
],
|
|
2128
|
+
success: true,
|
|
2129
|
+
message: 'No log files to clean',
|
|
2130
|
+
path: logsDir,
|
|
2131
|
+
totalFiles: files.length,
|
|
2132
|
+
logFiles: 0
|
|
2133
|
+
};
|
|
2134
|
+
}
|
|
2135
|
+
let totalSize = 0;
|
|
2136
|
+
let deletedCount = 0;
|
|
2137
|
+
const deletedFiles = [];
|
|
2138
|
+
for (const file of logFiles) {
|
|
2139
|
+
const filePath = path.join(logsDir, file);
|
|
2140
|
+
try {
|
|
2141
|
+
const stats = fs.statSync(filePath);
|
|
2142
|
+
totalSize += stats.size;
|
|
2143
|
+
fs.unlinkSync(filePath);
|
|
2144
|
+
deletedCount++;
|
|
2145
|
+
deletedFiles.push(file);
|
|
2146
|
+
}
|
|
2147
|
+
catch (error) {
|
|
2148
|
+
this.logger.warn(`Failed to delete log file ${file}:`, error);
|
|
2149
|
+
}
|
|
2150
|
+
}
|
|
2151
|
+
const formatSize = (bytes) => {
|
|
2152
|
+
if (bytes === 0)
|
|
2153
|
+
return '0 B';
|
|
2154
|
+
const k = 1024;
|
|
2155
|
+
const sizes = ['B', 'KB', 'MB', 'GB'];
|
|
2156
|
+
const i = Math.floor(Math.log(bytes) / Math.log(k));
|
|
2157
|
+
return parseFloat((bytes / Math.pow(k, i)).toFixed(2)) + ' ' + sizes[i];
|
|
2158
|
+
};
|
|
2159
|
+
return {
|
|
2160
|
+
content: [
|
|
2161
|
+
{
|
|
2162
|
+
type: 'text',
|
|
2163
|
+
text: `🗑️ **Log Cleanup Complete**
|
|
2164
|
+
|
|
2165
|
+
✅ **Successfully cleared all log files**
|
|
2166
|
+
|
|
2167
|
+
**Directory:** \`${logsDir}\`
|
|
2168
|
+
**Files deleted:** ${deletedCount}
|
|
2169
|
+
**Total space freed:** ${formatSize(totalSize)}
|
|
2170
|
+
|
|
2171
|
+
${deletedCount > 10 ?
|
|
2172
|
+
`**Sample deleted files:**
|
|
2173
|
+
${deletedFiles.slice(0, 10).map(f => ` • ${f}`).join('\n')}
|
|
2174
|
+
• ... and ${deletedCount - 10} more files` :
|
|
2175
|
+
`**Deleted files:**
|
|
2176
|
+
${deletedFiles.map(f => ` • ${f}`).join('\n')}`}
|
|
2177
|
+
|
|
2178
|
+
The logs directory is now clean and ready for new task logs. 🧹✨
|
|
2179
|
+
`
|
|
2180
|
+
}
|
|
2181
|
+
],
|
|
2182
|
+
success: true,
|
|
2183
|
+
message: 'All log files cleared successfully',
|
|
2184
|
+
path: logsDir,
|
|
2185
|
+
deletedCount,
|
|
2186
|
+
totalSize,
|
|
2187
|
+
deletedFiles: deletedFiles.slice(0, 20)
|
|
2188
|
+
};
|
|
2189
|
+
}
|
|
2190
|
+
catch (error) {
|
|
2191
|
+
this.logger.error('Failed to clear logs:', error);
|
|
2192
|
+
return {
|
|
2193
|
+
content: [
|
|
2194
|
+
{
|
|
2195
|
+
type: 'text',
|
|
2196
|
+
text: `❌ **Log Cleanup Failed**
|
|
2197
|
+
|
|
2198
|
+
**Error:** ${error.message}
|
|
2199
|
+
|
|
2200
|
+
Please check permissions and try again, or manually delete files from \`.crewx/logs/\` directory.
|
|
2201
|
+
`
|
|
2202
|
+
}
|
|
2203
|
+
],
|
|
2204
|
+
success: false,
|
|
2205
|
+
error: error.message
|
|
2206
|
+
};
|
|
2207
|
+
}
|
|
2208
|
+
}
|
|
2209
|
+
async getAvailableProvider(providerConfig) {
|
|
2210
|
+
const defaultFallbackOrder = ['claude', 'gemini', 'copilot'];
|
|
2211
|
+
let fallbackOrder;
|
|
2212
|
+
if (!providerConfig) {
|
|
2213
|
+
fallbackOrder = defaultFallbackOrder;
|
|
2214
|
+
}
|
|
2215
|
+
else if (Array.isArray(providerConfig)) {
|
|
2216
|
+
fallbackOrder = providerConfig;
|
|
2217
|
+
}
|
|
2218
|
+
else {
|
|
2219
|
+
fallbackOrder = [providerConfig, ...defaultFallbackOrder.filter(p => p !== providerConfig)];
|
|
2220
|
+
}
|
|
2221
|
+
for (const providerName of fallbackOrder) {
|
|
2222
|
+
const provider = this.aiProviderService.getProvider(providerName);
|
|
2223
|
+
if (provider) {
|
|
2224
|
+
const isAvailable = await provider.isAvailable();
|
|
2225
|
+
if (isAvailable) {
|
|
2226
|
+
if (fallbackOrder.indexOf(providerName) > 0) {
|
|
2227
|
+
this.logger.log(`Using fallback provider: ${providerName} (tried: ${fallbackOrder.slice(0, fallbackOrder.indexOf(providerName)).join(', ')})`);
|
|
2228
|
+
}
|
|
2229
|
+
return providerName;
|
|
2230
|
+
}
|
|
2231
|
+
}
|
|
2232
|
+
}
|
|
2233
|
+
this.logger.warn('No providers available, defaulting to claude');
|
|
2234
|
+
return 'claude';
|
|
2235
|
+
}
|
|
2236
|
+
resolveFileRemoteAgent(agent, agentId, taskId) {
|
|
2237
|
+
const fileRemote = this.remoteAgentService.resolveFileRemoteConfig(agent);
|
|
2238
|
+
if (!fileRemote)
|
|
2239
|
+
return {};
|
|
2240
|
+
const targetConfig = (0, crewx_sdk_1.parseCrewxConfigFromFile)(fileRemote.configPath);
|
|
2241
|
+
const targetAgent = targetConfig.agents?.find(a => a.id === fileRemote.externalAgentId);
|
|
2242
|
+
if (!targetAgent) {
|
|
2243
|
+
throw new Error(`Agent '${fileRemote.externalAgentId}' not found in ${fileRemote.configPath}`);
|
|
2244
|
+
}
|
|
2245
|
+
const targetProvider = Array.isArray(targetAgent.provider)
|
|
2246
|
+
? targetAgent.provider[0] : targetAgent.provider;
|
|
2247
|
+
if (typeof targetProvider === 'string' && targetProvider.startsWith('remote/')) {
|
|
2248
|
+
throw new Error(`Chained remotes not supported: ${fileRemote.externalAgentId} → ${targetProvider}`);
|
|
2249
|
+
}
|
|
2250
|
+
const targetDir = targetAgent.working_directory || path.dirname(fileRemote.configPath);
|
|
2251
|
+
this.logger.log(`[${taskId}] file:// remote: resolving '${fileRemote.externalAgentId}' via ${targetProvider}`);
|
|
2252
|
+
Object.assign(agent, targetAgent, {
|
|
2253
|
+
id: agentId,
|
|
2254
|
+
provider: targetProvider,
|
|
2255
|
+
workingDirectory: targetDir,
|
|
2256
|
+
});
|
|
2257
|
+
delete agent.remote;
|
|
2258
|
+
const wsInfo = this.tracingService?.resolveWorkspaceIdForPath(targetDir);
|
|
2259
|
+
return {
|
|
2260
|
+
workspaceId: wsInfo?.workspaceId,
|
|
2261
|
+
workspaceName: wsInfo?.workspaceName,
|
|
2262
|
+
};
|
|
2263
|
+
}
|
|
2264
|
+
};
|
|
2265
|
+
exports.CrewXTool = CrewXTool;
|
|
2266
|
+
__decorate([
|
|
2267
|
+
(0, nestjs_mcp_adapter_1.McpTool)({
|
|
2268
|
+
server: crewx_sdk_1.SERVER_NAME,
|
|
2269
|
+
name: `${crewx_sdk_1.PREFIX_TOOL_NAME}getTaskLogs`,
|
|
2270
|
+
description: 'Get task logs by task ID to monitor progress and detailed execution logs.',
|
|
2271
|
+
input: {
|
|
2272
|
+
taskId: zod_1.z.string().optional().describe('Task ID to get logs for. If not provided, returns all recent tasks.')
|
|
2273
|
+
},
|
|
2274
|
+
annotations: {
|
|
2275
|
+
title: 'Get Task Logs',
|
|
2276
|
+
readOnlyHint: true,
|
|
2277
|
+
desctructiveHint: false
|
|
2278
|
+
}
|
|
2279
|
+
}),
|
|
2280
|
+
__metadata("design:type", Function),
|
|
2281
|
+
__metadata("design:paramtypes", [Object]),
|
|
2282
|
+
__metadata("design:returntype", Promise)
|
|
2283
|
+
], CrewXTool.prototype, "getTaskLogs", null);
|
|
2284
|
+
__decorate([
|
|
2285
|
+
(0, nestjs_mcp_adapter_1.McpTool)({
|
|
2286
|
+
server: crewx_sdk_1.SERVER_NAME,
|
|
2287
|
+
name: `${crewx_sdk_1.PREFIX_TOOL_NAME}checkAIProviders`,
|
|
2288
|
+
description: 'Check the status of available AI CLI tools (Claude, Gemini, GitHub Copilot).',
|
|
2289
|
+
input: {},
|
|
2290
|
+
annotations: {
|
|
2291
|
+
title: 'Check AI Providers Status',
|
|
2292
|
+
readOnlyHint: true,
|
|
2293
|
+
desctructiveHint: false
|
|
2294
|
+
}
|
|
2295
|
+
}),
|
|
2296
|
+
__metadata("design:type", Function),
|
|
2297
|
+
__metadata("design:paramtypes", []),
|
|
2298
|
+
__metadata("design:returntype", Promise)
|
|
2299
|
+
], CrewXTool.prototype, "checkAIProviders", null);
|
|
2300
|
+
__decorate([
|
|
2301
|
+
(0, nestjs_mcp_adapter_1.McpTool)({
|
|
2302
|
+
server: crewx_sdk_1.SERVER_NAME,
|
|
2303
|
+
name: `${crewx_sdk_1.PREFIX_TOOL_NAME}listAgents`,
|
|
2304
|
+
description: 'List available specialist AI agents that can be utilized. Each agent is specialized in a specific domain.',
|
|
2305
|
+
input: {},
|
|
2306
|
+
annotations: {
|
|
2307
|
+
title: 'List Available AI Agents',
|
|
2308
|
+
readOnlyHint: true,
|
|
2309
|
+
desctructiveHint: false
|
|
2310
|
+
}
|
|
2311
|
+
}),
|
|
2312
|
+
__metadata("design:type", Function),
|
|
2313
|
+
__metadata("design:paramtypes", []),
|
|
2314
|
+
__metadata("design:returntype", Promise)
|
|
2315
|
+
], CrewXTool.prototype, "listAgents", null);
|
|
2316
|
+
__decorate([
|
|
2317
|
+
(0, nestjs_mcp_adapter_1.McpTool)({
|
|
2318
|
+
server: crewx_sdk_1.SERVER_NAME,
|
|
2319
|
+
name: `${crewx_sdk_1.PREFIX_TOOL_NAME}queryAgent`,
|
|
2320
|
+
description: 'Query a specific specialist agent (read-only mode). You can request code analysis, explanations, reviews, etc. No file modifications will be performed.',
|
|
2321
|
+
input: {
|
|
2322
|
+
agentId: zod_1.z.string().describe('Agent ID to query (e.g., frontend_developer, backend_developer, devops_engineer, security_analyst, or custom agents)'),
|
|
2323
|
+
query: zod_1.z.string().describe('Question or request to ask the agent'),
|
|
2324
|
+
projectPath: zod_1.z.string().describe('Absolute path of the project to analyze').optional(),
|
|
2325
|
+
context: zod_1.z.string().describe('Additional context or background information').optional(),
|
|
2326
|
+
model: zod_1.z.string().describe('Model to use for this query (e.g., sonnet, gemini-2.5-pro, gpt-5)').optional(),
|
|
2327
|
+
messages: zod_1.z.array(zod_1.z.object({
|
|
2328
|
+
text: zod_1.z.string(),
|
|
2329
|
+
isAssistant: zod_1.z.boolean(),
|
|
2330
|
+
metadata: zod_1.z.record(zod_1.z.any()).optional(),
|
|
2331
|
+
files: zod_1.z.array(zod_1.z.object({
|
|
2332
|
+
id: zod_1.z.string(),
|
|
2333
|
+
name: zod_1.z.string(),
|
|
2334
|
+
mimetype: zod_1.z.string().optional(),
|
|
2335
|
+
size: zod_1.z.number().optional(),
|
|
2336
|
+
localPath: zod_1.z.string().optional(),
|
|
2337
|
+
url: zod_1.z.string().optional(),
|
|
2338
|
+
})).optional(),
|
|
2339
|
+
})).describe('Conversation history to provide as context (oldest → newest)').optional(),
|
|
2340
|
+
platform: zod_1.z.enum(['cli', 'slack']).optional(),
|
|
2341
|
+
metadata: zod_1.z.record(zod_1.z.any()).optional(),
|
|
2342
|
+
},
|
|
2343
|
+
annotations: {
|
|
2344
|
+
title: 'Query Specialist Agent (Read-Only)',
|
|
2345
|
+
readOnlyHint: true,
|
|
2346
|
+
desctructiveHint: false
|
|
2347
|
+
}
|
|
2348
|
+
}),
|
|
2349
|
+
__metadata("design:type", Function),
|
|
2350
|
+
__metadata("design:paramtypes", [Object]),
|
|
2351
|
+
__metadata("design:returntype", Promise)
|
|
2352
|
+
], CrewXTool.prototype, "queryAgent", null);
|
|
2353
|
+
__decorate([
|
|
2354
|
+
(0, nestjs_mcp_adapter_1.McpTool)({
|
|
2355
|
+
server: crewx_sdk_1.SERVER_NAME,
|
|
2356
|
+
name: `${crewx_sdk_1.PREFIX_TOOL_NAME}executeAgent`,
|
|
2357
|
+
description: 'Execute tasks through a specialist agent. Can provide implementation guidance, code examples, and actionable solutions.',
|
|
2358
|
+
input: {
|
|
2359
|
+
agentId: zod_1.z.string().describe('Agent ID to execute (e.g., frontend_developer, backend_developer, devops_engineer, security_analyst, or custom agents)'),
|
|
2360
|
+
task: zod_1.z.string().describe('Task or implementation request for the agent to perform'),
|
|
2361
|
+
projectPath: zod_1.z.string().describe('Absolute path of the project to work on').optional(),
|
|
2362
|
+
context: zod_1.z.string().describe('Additional context or background information').optional(),
|
|
2363
|
+
model: zod_1.z.string().describe('Model to use for this execution (e.g., sonnet, gemini-2.5-pro, gpt-5)').optional(),
|
|
2364
|
+
messages: zod_1.z.array(zod_1.z.object({
|
|
2365
|
+
text: zod_1.z.string(),
|
|
2366
|
+
isAssistant: zod_1.z.boolean(),
|
|
2367
|
+
metadata: zod_1.z.record(zod_1.z.any()).optional(),
|
|
2368
|
+
files: zod_1.z.array(zod_1.z.object({
|
|
2369
|
+
id: zod_1.z.string(),
|
|
2370
|
+
name: zod_1.z.string(),
|
|
2371
|
+
mimetype: zod_1.z.string().optional(),
|
|
2372
|
+
size: zod_1.z.number().optional(),
|
|
2373
|
+
localPath: zod_1.z.string().optional(),
|
|
2374
|
+
url: zod_1.z.string().optional(),
|
|
2375
|
+
})).optional(),
|
|
2376
|
+
})).describe('Conversation history to provide as context (oldest → newest)').optional(),
|
|
2377
|
+
platform: zod_1.z.enum(['cli', 'slack']).optional(),
|
|
2378
|
+
metadata: zod_1.z.record(zod_1.z.any()).optional(),
|
|
2379
|
+
},
|
|
2380
|
+
annotations: {
|
|
2381
|
+
title: 'Execute Agent Task (Can Modify Files)',
|
|
2382
|
+
readOnlyHint: false,
|
|
2383
|
+
desctructiveHint: true
|
|
2384
|
+
}
|
|
2385
|
+
}),
|
|
2386
|
+
__metadata("design:type", Function),
|
|
2387
|
+
__metadata("design:paramtypes", [Object]),
|
|
2388
|
+
__metadata("design:returntype", Promise)
|
|
2389
|
+
], CrewXTool.prototype, "executeAgent", null);
|
|
2390
|
+
__decorate([
|
|
2391
|
+
(0, nestjs_mcp_adapter_1.McpTool)({
|
|
2392
|
+
server: crewx_sdk_1.SERVER_NAME,
|
|
2393
|
+
name: `${crewx_sdk_1.PREFIX_TOOL_NAME}queryAgentParallel`,
|
|
2394
|
+
description: 'Query multiple specialist agents simultaneously in parallel (read-only mode). Efficiently send multiple tasks to the same agent or different questions to various agents.',
|
|
2395
|
+
input: {
|
|
2396
|
+
queries: zod_1.z.array(zod_1.z.object({
|
|
2397
|
+
agentId: zod_1.z.string().describe('Agent ID to query (e.g., frontend_developer, backend_developer, gmail_mcp_developer, etc.)'),
|
|
2398
|
+
query: zod_1.z.string().describe('Question or request to ask the agent'),
|
|
2399
|
+
projectPath: zod_1.z.string().describe('Absolute path of the project to analyze').optional(),
|
|
2400
|
+
context: zod_1.z.string().describe('Additional context or background information').optional(),
|
|
2401
|
+
model: zod_1.z.string().describe('Model to use for this query').optional(),
|
|
2402
|
+
messages: zod_1.z.array(zod_1.z.object({
|
|
2403
|
+
text: zod_1.z.string(),
|
|
2404
|
+
isAssistant: zod_1.z.boolean(),
|
|
2405
|
+
metadata: zod_1.z.record(zod_1.z.any()).optional(),
|
|
2406
|
+
files: zod_1.z.array(zod_1.z.object({
|
|
2407
|
+
id: zod_1.z.string(),
|
|
2408
|
+
name: zod_1.z.string(),
|
|
2409
|
+
mimetype: zod_1.z.string().optional(),
|
|
2410
|
+
size: zod_1.z.number().optional(),
|
|
2411
|
+
localPath: zod_1.z.string().optional(),
|
|
2412
|
+
url: zod_1.z.string().optional(),
|
|
2413
|
+
})).optional(),
|
|
2414
|
+
})).describe('Conversation history to provide as context (oldest → newest)').optional(),
|
|
2415
|
+
})).describe('Array of queries to process in parallel'),
|
|
2416
|
+
},
|
|
2417
|
+
annotations: {
|
|
2418
|
+
title: 'Query Multiple Agents in Parallel (Read-Only)',
|
|
2419
|
+
readOnlyHint: true,
|
|
2420
|
+
desctructiveHint: false
|
|
2421
|
+
}
|
|
2422
|
+
}),
|
|
2423
|
+
__metadata("design:type", Function),
|
|
2424
|
+
__metadata("design:paramtypes", [Object]),
|
|
2425
|
+
__metadata("design:returntype", Promise)
|
|
2426
|
+
], CrewXTool.prototype, "queryAgentParallel", null);
|
|
2427
|
+
__decorate([
|
|
2428
|
+
(0, nestjs_mcp_adapter_1.McpTool)({
|
|
2429
|
+
server: crewx_sdk_1.SERVER_NAME,
|
|
2430
|
+
name: `${crewx_sdk_1.PREFIX_TOOL_NAME}executeAgentParallel`,
|
|
2431
|
+
description: 'Execute multiple tasks through specialist agents simultaneously in parallel (execution mode). Efficiently distribute implementation work across multiple agents.',
|
|
2432
|
+
input: {
|
|
2433
|
+
tasks: zod_1.z.array(zod_1.z.object({
|
|
2434
|
+
agentId: zod_1.z.string().describe('Agent ID to execute (e.g., frontend_developer, backend_developer, crewx_developer_claude, etc.)'),
|
|
2435
|
+
task: zod_1.z.string().describe('Task or implementation request for the agent to perform'),
|
|
2436
|
+
projectPath: zod_1.z.string().describe('Absolute path of the project to work on').optional(),
|
|
2437
|
+
context: zod_1.z.string().describe('Additional context or background information').optional(),
|
|
2438
|
+
model: zod_1.z.string().describe('Model to use for this execution').optional(),
|
|
2439
|
+
messages: zod_1.z.array(zod_1.z.object({
|
|
2440
|
+
text: zod_1.z.string(),
|
|
2441
|
+
isAssistant: zod_1.z.boolean(),
|
|
2442
|
+
metadata: zod_1.z.record(zod_1.z.any()).optional(),
|
|
2443
|
+
files: zod_1.z.array(zod_1.z.object({
|
|
2444
|
+
id: zod_1.z.string(),
|
|
2445
|
+
name: zod_1.z.string(),
|
|
2446
|
+
mimetype: zod_1.z.string().optional(),
|
|
2447
|
+
size: zod_1.z.number().optional(),
|
|
2448
|
+
localPath: zod_1.z.string().optional(),
|
|
2449
|
+
url: zod_1.z.string().optional(),
|
|
2450
|
+
})).optional(),
|
|
2451
|
+
})).describe('Conversation history to provide as context (oldest → newest)').optional(),
|
|
2452
|
+
})).describe('Array of tasks to execute in parallel'),
|
|
2453
|
+
},
|
|
2454
|
+
annotations: {
|
|
2455
|
+
title: 'Execute Multiple Agent Tasks in Parallel (Can Modify Files)',
|
|
2456
|
+
readOnlyHint: false,
|
|
2457
|
+
desctructiveHint: true
|
|
2458
|
+
}
|
|
2459
|
+
}),
|
|
2460
|
+
__metadata("design:type", Function),
|
|
2461
|
+
__metadata("design:paramtypes", [Object]),
|
|
2462
|
+
__metadata("design:returntype", Promise)
|
|
2463
|
+
], CrewXTool.prototype, "executeAgentParallel", null);
|
|
2464
|
+
__decorate([
|
|
2465
|
+
(0, nestjs_mcp_adapter_1.McpTool)({
|
|
2466
|
+
server: crewx_sdk_1.SERVER_NAME,
|
|
2467
|
+
name: `${crewx_sdk_1.PREFIX_TOOL_NAME}clearAllLogs`,
|
|
2468
|
+
description: 'Clear all log files from the .crewx/logs directory to clean up accumulated task logs',
|
|
2469
|
+
input: {},
|
|
2470
|
+
annotations: {
|
|
2471
|
+
title: 'Clear All Logs',
|
|
2472
|
+
readOnlyHint: false,
|
|
2473
|
+
}
|
|
2474
|
+
}),
|
|
2475
|
+
__metadata("design:type", Function),
|
|
2476
|
+
__metadata("design:paramtypes", []),
|
|
2477
|
+
__metadata("design:returntype", Promise)
|
|
2478
|
+
], CrewXTool.prototype, "clearAllLogs", null);
|
|
2479
|
+
exports.CrewXTool = CrewXTool = CrewXTool_1 = __decorate([
|
|
2480
|
+
(0, common_1.Injectable)(),
|
|
2481
|
+
__param(13, (0, common_1.Inject)('LAYOUT_LOADER')),
|
|
2482
|
+
__param(14, (0, common_1.Inject)('LAYOUT_RENDERER')),
|
|
2483
|
+
__param(15, (0, common_1.Optional)()),
|
|
2484
|
+
__metadata("design:paramtypes", [ai_service_1.AIService,
|
|
2485
|
+
ai_provider_service_1.AIProviderService,
|
|
2486
|
+
workspace_service_1.WorkspaceService,
|
|
2487
|
+
parallel_processing_service_1.ParallelProcessingService,
|
|
2488
|
+
task_management_service_1.TaskManagementService,
|
|
2489
|
+
result_formatter_service_1.ResultFormatterService,
|
|
2490
|
+
template_service_1.TemplateService,
|
|
2491
|
+
document_loader_service_1.DocumentLoaderService,
|
|
2492
|
+
tool_call_service_1.ToolCallService,
|
|
2493
|
+
agent_loader_service_1.AgentLoaderService,
|
|
2494
|
+
remote_agent_service_1.RemoteAgentService,
|
|
2495
|
+
provider_bridge_service_1.ProviderBridgeService,
|
|
2496
|
+
skill_loader_service_1.SkillLoaderService,
|
|
2497
|
+
crewx_sdk_1.LayoutLoader,
|
|
2498
|
+
crewx_sdk_1.LayoutRenderer,
|
|
2499
|
+
tracing_service_1.TracingService])
|
|
2500
|
+
], CrewXTool);
|
|
2501
|
+
//# sourceMappingURL=crewx.tool.js.map
|