@sowonai/crewx-cli 0.4.0-dev.3 → 0.4.0-dev.30

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.
Files changed (89) hide show
  1. package/README.md +40 -6
  2. package/dist/ai-provider.service.d.ts +7 -12
  3. package/dist/ai-provider.service.js +41 -19
  4. package/dist/ai-provider.service.js.map +1 -1
  5. package/dist/ai.service.d.ts +5 -45
  6. package/dist/ai.service.js +7 -584
  7. package/dist/ai.service.js.map +1 -1
  8. package/dist/app.module.js +67 -9
  9. package/dist/app.module.js.map +1 -1
  10. package/dist/cli/chat.handler.d.ts +2 -1
  11. package/dist/cli/chat.handler.js +26 -11
  12. package/dist/cli/chat.handler.js.map +1 -1
  13. package/dist/cli/doctor.handler.js +8 -40
  14. package/dist/cli/doctor.handler.js.map +1 -1
  15. package/dist/cli/execute.handler.js +8 -6
  16. package/dist/cli/execute.handler.js.map +1 -1
  17. package/dist/cli/mcp.handler.js.map +1 -1
  18. package/dist/cli/query.handler.js +4 -2
  19. package/dist/cli/query.handler.js.map +1 -1
  20. package/dist/cli-options.d.ts +2 -0
  21. package/dist/cli-options.js +10 -0
  22. package/dist/cli-options.js.map +1 -1
  23. package/dist/crewx.tool.d.ts +18 -2
  24. package/dist/crewx.tool.js +509 -105
  25. package/dist/crewx.tool.js.map +1 -1
  26. package/dist/providers/dynamic-provider.factory.d.ts +9 -51
  27. package/dist/providers/dynamic-provider.factory.js +44 -506
  28. package/dist/providers/dynamic-provider.factory.js.map +1 -1
  29. package/dist/providers/logger.adapter.d.ts +4 -0
  30. package/dist/providers/logger.adapter.js +56 -0
  31. package/dist/providers/logger.adapter.js.map +1 -0
  32. package/dist/services/agent-loader.service.d.ts +6 -2
  33. package/dist/services/agent-loader.service.js +207 -25
  34. package/dist/services/agent-loader.service.js.map +1 -1
  35. package/dist/services/config.service.d.ts +7 -27
  36. package/dist/services/config.service.js +80 -38
  37. package/dist/services/config.service.js.map +1 -1
  38. package/dist/services/parallel-processing.service.d.ts +17 -17
  39. package/dist/services/parallel-processing.service.js +259 -196
  40. package/dist/services/parallel-processing.service.js.map +1 -1
  41. package/dist/services/provider-bridge.service.d.ts +35 -0
  42. package/dist/services/provider-bridge.service.js +224 -0
  43. package/dist/services/provider-bridge.service.js.map +1 -0
  44. package/dist/services/remote-agent.service.d.ts +4 -7
  45. package/dist/services/remote-agent.service.js +41 -95
  46. package/dist/services/remote-agent.service.js.map +1 -1
  47. package/dist/services/template.service.d.ts +2 -0
  48. package/dist/services/template.service.js +46 -1
  49. package/dist/services/template.service.js.map +1 -1
  50. package/dist/services/tool-call.service.d.ts +2 -36
  51. package/dist/services/tool-call.service.js.map +1 -1
  52. package/dist/slack/formatters/message.formatter.d.ts +5 -2
  53. package/dist/slack/formatters/message.formatter.js +55 -2
  54. package/dist/slack/formatters/message.formatter.js.map +1 -1
  55. package/dist/slack/slack-bot.js +1 -2
  56. package/dist/slack/slack-bot.js.map +1 -1
  57. package/dist/utils/stdin-utils.d.ts +4 -25
  58. package/dist/utils/stdin-utils.js +2 -23
  59. package/dist/utils/stdin-utils.js.map +1 -1
  60. package/dist/utils/template-processor.d.ts +2 -29
  61. package/dist/utils/template-processor.js +1 -1
  62. package/dist/utils/template-processor.js.map +1 -1
  63. package/dist/utils/terminal-message-formatter.d.ts +23 -0
  64. package/dist/utils/terminal-message-formatter.js +136 -0
  65. package/dist/utils/terminal-message-formatter.js.map +1 -0
  66. package/package.json +2 -3
  67. package/scripts/postbuild-cli.mjs +20 -1
  68. package/templates/agents/default.yaml +1066 -0
  69. package/templates/agents/minimal.yaml +16 -0
  70. package/templates/documents/crewcode-manual.md +292 -0
  71. package/templates/versions.json +19 -0
  72. package/dist/providers/base-ai.provider.d.ts +0 -50
  73. package/dist/providers/base-ai.provider.js +0 -624
  74. package/dist/providers/base-ai.provider.js.map +0 -1
  75. package/dist/providers/claude.provider.d.ts +0 -25
  76. package/dist/providers/claude.provider.js +0 -362
  77. package/dist/providers/claude.provider.js.map +0 -1
  78. package/dist/providers/codex.provider.d.ts +0 -17
  79. package/dist/providers/codex.provider.js +0 -99
  80. package/dist/providers/codex.provider.js.map +0 -1
  81. package/dist/providers/copilot.provider.d.ts +0 -25
  82. package/dist/providers/copilot.provider.js +0 -266
  83. package/dist/providers/copilot.provider.js.map +0 -1
  84. package/dist/providers/gemini.provider.d.ts +0 -22
  85. package/dist/providers/gemini.provider.js +0 -147
  86. package/dist/providers/gemini.provider.js.map +0 -1
  87. package/dist/utils/mention-parser.d.ts +0 -18
  88. package/dist/utils/mention-parser.js +0 -136
  89. package/dist/utils/mention-parser.js.map +0 -1
@@ -41,9 +41,13 @@ var __importStar = (this && this.__importStar) || (function () {
41
41
  var __metadata = (this && this.__metadata) || function (k, v) {
42
42
  if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
43
43
  };
44
+ var __param = (this && this.__param) || function (paramIndex, decorator) {
45
+ return function (target, key) { decorator(target, key, paramIndex); }
46
+ };
44
47
  var CrewXTool_1;
45
48
  Object.defineProperty(exports, "__esModule", { value: true });
46
49
  exports.CrewXTool = void 0;
50
+ const crewx_sdk_1 = require("@sowonai/crewx-sdk");
47
51
  const common_1 = require("@nestjs/common");
48
52
  const nestjs_mcp_adapter_1 = require("@sowonai/nestjs-mcp-adapter");
49
53
  const zod_1 = require("zod");
@@ -53,7 +57,6 @@ const crypto = __importStar(require("crypto"));
53
57
  const ai_service_1 = require("./ai.service");
54
58
  const ai_provider_service_1 = require("./ai-provider.service");
55
59
  const project_service_1 = require("./project.service");
56
- const crewx_sdk_1 = require("@sowonai/crewx-sdk");
57
60
  const parallel_processing_service_1 = require("./services/parallel-processing.service");
58
61
  const task_management_service_1 = require("./services/task-management.service");
59
62
  const result_formatter_service_1 = require("./services/result-formatter.service");
@@ -62,6 +65,7 @@ const document_loader_service_1 = require("./services/document-loader.service");
62
65
  const tool_call_service_1 = require("./services/tool-call.service");
63
66
  const agent_loader_service_1 = require("./services/agent-loader.service");
64
67
  const remote_agent_service_1 = require("./services/remote-agent.service");
68
+ const provider_bridge_service_1 = require("./services/provider-bridge.service");
65
69
  let CrewXTool = CrewXTool_1 = class CrewXTool {
66
70
  generateSecurityKey() {
67
71
  return crypto.randomBytes(8).toString('hex');
@@ -122,7 +126,7 @@ let CrewXTool = CrewXTool_1 = class CrewXTool {
122
126
  };
123
127
  return JSON.stringify(payload);
124
128
  }
125
- constructor(aiService, aiProviderService, projectService, parallelProcessingService, taskManagementService, resultFormatterService, templateService, documentLoaderService, toolCallService, agentLoaderService, remoteAgentService) {
129
+ constructor(aiService, aiProviderService, projectService, parallelProcessingService, taskManagementService, resultFormatterService, templateService, documentLoaderService, toolCallService, agentLoaderService, remoteAgentService, providerBridgeService, layoutLoader, layoutRenderer) {
126
130
  this.aiService = aiService;
127
131
  this.aiProviderService = aiProviderService;
128
132
  this.projectService = projectService;
@@ -134,6 +138,9 @@ let CrewXTool = CrewXTool_1 = class CrewXTool {
134
138
  this.toolCallService = toolCallService;
135
139
  this.agentLoaderService = agentLoaderService;
136
140
  this.remoteAgentService = remoteAgentService;
141
+ this.providerBridgeService = providerBridgeService;
142
+ this.layoutLoader = layoutLoader;
143
+ this.layoutRenderer = layoutRenderer;
137
144
  this.logger = new common_1.Logger(CrewXTool_1.name);
138
145
  this.timeoutConfig = (0, crewx_sdk_1.getTimeoutConfig)();
139
146
  }
@@ -141,6 +148,112 @@ let CrewXTool = CrewXTool_1 = class CrewXTool {
141
148
  this.toolCallService.setCrewXTool(this);
142
149
  this.logger.log('CrewXTool registered to ToolCallService');
143
150
  }
151
+ async processAgentSystemPrompt(agent, templateContext) {
152
+ const inlineLayout = agent.inline?.layout;
153
+ const baseSystemPrompt = agent.inline?.prompt ||
154
+ agent.inline?.system_prompt ||
155
+ agent.systemPrompt ||
156
+ agent.description ||
157
+ `You are an expert ${agent.id}.`;
158
+ const layoutSpec = inlineLayout ?? 'crewx/default';
159
+ if (layoutSpec) {
160
+ const layoutId = typeof layoutSpec === 'string' ? layoutSpec : layoutSpec.id;
161
+ const layoutProps = typeof layoutSpec === 'object' && layoutSpec !== null && 'props' in layoutSpec
162
+ ? layoutSpec.props
163
+ : undefined;
164
+ try {
165
+ console.log(`[DEBUG] Loading layout: ${layoutId} for agent ${agent.id}`);
166
+ const layout = this.layoutLoader.load(layoutId, layoutProps);
167
+ console.log(`[DEBUG] Loaded layout ID: ${layout.id}, template length: ${layout.template.length}`);
168
+ const providerRaw = agent.provider;
169
+ const providerList = Array.isArray(providerRaw)
170
+ ? providerRaw
171
+ : (typeof providerRaw === 'string' && providerRaw.length > 0)
172
+ ? [providerRaw]
173
+ : [];
174
+ const providerDisplay = providerList.length > 0
175
+ ? providerList.join(', ')
176
+ : (typeof providerRaw === 'string' ? providerRaw : '');
177
+ const inlineConfig = agent.inline
178
+ ? { ...agent.inline, prompt: baseSystemPrompt }
179
+ : { prompt: baseSystemPrompt };
180
+ const templateOptions = [];
181
+ const sessionInfo = {
182
+ mode: templateContext.mode ?? 'query',
183
+ platform: templateContext.platform ?? 'cli',
184
+ options: templateOptions,
185
+ env: templateContext.env ?? {},
186
+ vars: templateContext.vars ?? {},
187
+ tools: templateContext.tools ?? null,
188
+ };
189
+ const renderContext = {
190
+ user_input: templateContext.user_input,
191
+ agent: {
192
+ id: agent.id,
193
+ name: agent.name || agent.id,
194
+ role: agent.role || '',
195
+ team: agent.team || '',
196
+ description: agent.description || '',
197
+ workingDirectory: agent.workingDirectory,
198
+ capabilities: agent.capabilities || [],
199
+ specialties: agent.specialties || [],
200
+ provider: providerDisplay,
201
+ providerList,
202
+ providerRaw,
203
+ inline: inlineConfig,
204
+ model: agent.inline?.model,
205
+ options: agent.options ?? {},
206
+ optionsArray: Array.isArray(agent.options) ? agent.options : undefined,
207
+ optionsByMode: !Array.isArray(agent.options) && typeof agent.options === 'object'
208
+ ? agent.options
209
+ : undefined,
210
+ remote: agent.remote ?? null,
211
+ documents: agent.inline && 'documents' in agent.inline ? agent.inline.documents : undefined,
212
+ },
213
+ documents: {},
214
+ vars: templateContext.vars || {},
215
+ props: layoutProps ?? {},
216
+ messages: templateContext.messages || [],
217
+ platform: templateContext.platform ?? 'cli',
218
+ tools: templateContext.tools,
219
+ session: sessionInfo,
220
+ env: templateContext.env ?? {},
221
+ context: {
222
+ mode: templateContext.mode ?? 'query',
223
+ platform: templateContext.platform ?? 'cli',
224
+ options: templateOptions,
225
+ env: templateContext.env ?? {},
226
+ vars: templateContext.vars ?? {},
227
+ agent: templateContext.agent ?? null,
228
+ },
229
+ };
230
+ renderContext.layout = {
231
+ system_prompt: baseSystemPrompt,
232
+ prompt: baseSystemPrompt,
233
+ };
234
+ const rendered = this.layoutRenderer.render(layout, renderContext);
235
+ this.logger.debug(`Layout rendered successfully for agent ${agent.id}`);
236
+ const { processDocumentTemplate } = await Promise.resolve().then(() => __importStar(require('./utils/template-processor')));
237
+ return await processDocumentTemplate(rendered, this.documentLoaderService, templateContext);
238
+ }
239
+ catch (error) {
240
+ const layoutIdForLog = typeof layoutSpec === 'string' ? layoutSpec : layoutSpec.id;
241
+ this.logger.warn(`Failed to process layout (${layoutIdForLog}) for agent ${agent.id}: ${(0, crewx_sdk_1.getErrorMessage)(error)}`);
242
+ if (inlineLayout) {
243
+ this.logger.warn('Falling back to inline.system_prompt');
244
+ }
245
+ else {
246
+ this.logger.warn('Falling back to default system prompt');
247
+ }
248
+ }
249
+ }
250
+ let systemPrompt = baseSystemPrompt;
251
+ if (systemPrompt) {
252
+ const { processDocumentTemplate } = await Promise.resolve().then(() => __importStar(require('./utils/template-processor')));
253
+ systemPrompt = await processDocumentTemplate(systemPrompt, this.documentLoaderService, templateContext);
254
+ }
255
+ return systemPrompt;
256
+ }
144
257
  async getTaskLogs(input) {
145
258
  this.logger.log('=== getTaskLogs called ===');
146
259
  this.logger.log(`Input taskId: ${input.taskId}`);
@@ -165,11 +278,29 @@ let CrewXTool = CrewXTool_1 = class CrewXTool {
165
278
  const availableProviders = await this.aiService.checkAvailableProviders();
166
279
  const installation = await this.aiService.validateCLIInstallation();
167
280
  const recommendations = this.getInstallationRecommendations(installation);
281
+ const bridgeProviders = this.providerBridgeService.listAvailableProviders();
282
+ let bridgeStatus = '⚠️ ProviderBridge: no providers registered.';
283
+ if (bridgeProviders.length > 0) {
284
+ try {
285
+ const { resolution } = await this.providerBridgeService.createAgentRuntime({
286
+ provider: bridgeProviders[0],
287
+ defaultAgentId: 'provider-bridge-check',
288
+ });
289
+ bridgeStatus = `✅ ProviderBridge ready (${resolution.provider.name})`;
290
+ }
291
+ catch (error) {
292
+ const message = error instanceof Error ? error.message : String(error);
293
+ bridgeStatus = `❌ ProviderBridge error: ${message}`;
294
+ }
295
+ }
168
296
  const responseText = `🤖 **AI Providers Status**
169
297
 
170
298
  **Available Providers:**
171
299
  ${availableProviders.length > 0 ? availableProviders.map(p => `✅ ${p}`).join('\n') : '❌ No providers available'}
172
300
 
301
+ **Provider Bridge:**
302
+ ${bridgeStatus}${bridgeProviders.length > 0 ? `\nRegistered: ${bridgeProviders.join(', ')}` : ''}
303
+
173
304
  **Installation Status:**
174
305
  • Claude CLI: ${installation.claude ? '✅ Installed' : '❌ Not Installed'}
175
306
  • Gemini CLI: ${installation.gemini ? '✅ Installed' : '❌ Not Installed'}
@@ -191,6 +322,10 @@ ${recommendations.map(r => `• ${r}`).join('\n')}`;
191
322
  gemini: installation.gemini,
192
323
  copilot: installation.copilot,
193
324
  },
325
+ providerBridge: {
326
+ status: bridgeStatus,
327
+ providers: bridgeProviders,
328
+ },
194
329
  recommendations,
195
330
  };
196
331
  }
@@ -215,7 +350,11 @@ No AI providers could be verified.`
215
350
  claude: { installed: false },
216
351
  gemini: { installed: false },
217
352
  copilot: { installed: false }
218
- }
353
+ },
354
+ providerBridge: {
355
+ status: '❌ ProviderBridge inspection skipped due to error',
356
+ providers: [],
357
+ },
219
358
  };
220
359
  }
221
360
  }
@@ -349,6 +488,7 @@ agents:
349
488
  }
350
489
  const agents = await this.agentLoaderService.getAllAgents();
351
490
  const agent = agents.find(a => a.id === agentId);
491
+ console.log(`[DEBUG queryAgent] Agent: ${agentId}, hasInline: ${!!agent?.inline}, layout: ${agent?.inline?.layout}, provider: ${agent?.provider}`);
352
492
  if (!agent) {
353
493
  return {
354
494
  content: [
@@ -416,63 +556,137 @@ ${errorMessage}`,
416
556
  }
417
557
  }
418
558
  const workingDir = agent.workingDirectory || process.cwd();
419
- let systemPrompt = agent.systemPrompt || agent.description || `You are an expert ${agentId}.`;
420
559
  const securityKey = this.generateSecurityKey();
421
- if (systemPrompt) {
422
- const { processDocumentTemplate } = await Promise.resolve().then(() => __importStar(require('./utils/template-processor')));
423
- const contextMessages = messages && messages.length > 0 ? messages.slice(0, -1) : [];
424
- const templateContext = {
425
- env: process.env,
426
- agent: {
427
- id: agent.id,
428
- name: agent.name || agent.id,
429
- provider: (Array.isArray(agent.provider) ? agent.provider[0] : agent.provider) || 'claude',
430
- model: model || agent.inline?.model,
431
- workingDirectory: workingDir,
432
- },
433
- mode: 'query',
434
- messages: contextMessages,
435
- platform: platform,
436
- tools: this.buildToolsContext(),
437
- vars: {
438
- security_key: securityKey,
560
+ const contextMessages = messages && messages.length > 0 ? messages.slice(0, -1) : [];
561
+ const templateContext = {
562
+ user_input: query,
563
+ messages: contextMessages,
564
+ agent: {
565
+ id: agent.id,
566
+ name: agent.name || agent.id,
567
+ provider: (Array.isArray(agent.provider) ? agent.provider[0] : agent.provider) || 'claude',
568
+ model: model || agent.inline?.model,
569
+ workingDirectory: workingDir,
570
+ inline: {
571
+ prompt: agent.inline?.prompt || agent.inline?.system_prompt || agent.systemPrompt || '',
439
572
  },
440
- };
441
- systemPrompt = await processDocumentTemplate(systemPrompt, this.documentLoaderService, templateContext);
442
- }
443
- systemPrompt += `
573
+ specialties: agent.specialties,
574
+ capabilities: agent.capabilities,
575
+ description: agent.description,
576
+ },
577
+ documents: {},
578
+ vars: {
579
+ security_key: securityKey,
580
+ },
581
+ props: {},
582
+ mode: 'query',
583
+ platform: platform,
584
+ env: process.env,
585
+ tools: this.buildToolsContext(),
586
+ };
587
+ let systemPrompt = await this.processAgentSystemPrompt(agent, templateContext);
588
+ if (process.env.CREWX_APPEND_LEGACY === 'true') {
589
+ this.logger.debug('[WBS-14] Legacy append mode enabled (query)', {
590
+ agentId: agent.id,
591
+ layoutId: typeof agent.inline?.layout === 'string'
592
+ ? agent.inline?.layout
593
+ : agent.inline?.layout?.id ?? 'crewx/default',
594
+ });
595
+ systemPrompt += `
444
596
 
445
597
  Specialties: ${agent.specialties?.join(', ') || 'General'}
446
598
  Capabilities: ${agent.capabilities?.join(', ') || 'Analysis'}
447
599
  Working Directory: ${workingDir}`;
448
- const wrappedQuery = `
449
- <user_query key="${securityKey}">
450
- ${query}
451
- </user_query>`;
600
+ }
601
+ else if (process.env.CREWX_WBS14_TELEMETRY === 'true') {
602
+ this.logger.debug('[WBS-14] Metadata delegated to layout (query mode)', {
603
+ agentId: agent.id,
604
+ hasLayout: Boolean(agent.inline?.layout),
605
+ layoutId: typeof agent.inline?.layout === 'string'
606
+ ? agent.inline?.layout
607
+ : agent.inline?.layout?.id ?? 'crewx/default',
608
+ specialtiesCount: agent.specialties?.length ?? 0,
609
+ capabilitiesCount: agent.capabilities?.length ?? 0,
610
+ workingDirectory: workingDir,
611
+ });
612
+ }
452
613
  let fullPrompt = systemPrompt;
453
614
  if (context) {
454
615
  fullPrompt += `\n\n${context}`;
455
616
  }
456
- fullPrompt += `\n\n${wrappedQuery}`;
457
- let response;
458
- let provider;
459
- if (Array.isArray(agent.provider)) {
460
- if (agent.inline?.model || model) {
461
- provider = agent.provider[0] || 'claude';
462
- }
463
- else {
464
- provider = await this.getAvailableProvider(agent.provider);
465
- this.taskManagementService.addTaskLog(taskId, { level: 'info', message: `Using fallback provider: ${provider}` });
466
- }
617
+ if (!systemPrompt.includes('<user_query')) {
618
+ this.logger.debug('[Legacy] Adding <user_query> wrapper manually (layout not used)');
619
+ fullPrompt += `\n\n<user_query key="${securityKey}">
620
+ ${query}
621
+ </user_query>`;
622
+ }
623
+ let runtimeResult;
624
+ let providerResolution;
625
+ let providerInput;
626
+ if (args.provider) {
627
+ providerInput = args.provider;
628
+ }
629
+ else if (Array.isArray(agent.provider)) {
630
+ providerInput = await this.getAvailableProvider(agent.provider);
631
+ }
632
+ else if (typeof agent.provider === 'string' && agent.provider.trim().length > 0) {
633
+ providerInput = agent.provider;
634
+ }
635
+ try {
636
+ runtimeResult = await this.providerBridgeService.createAgentRuntime({
637
+ provider: providerInput,
638
+ defaultAgentId: agentId,
639
+ validAgents: agents.map(a => a.id),
640
+ });
641
+ providerResolution = runtimeResult.resolution;
642
+ }
643
+ catch (error) {
644
+ const errorMsg = error instanceof Error ? error.message : 'Unknown provider error';
645
+ this.taskManagementService.addTaskLog(taskId, {
646
+ level: 'error',
647
+ message: `Provider resolution failed: ${errorMsg}`,
648
+ });
649
+ this.taskManagementService.completeTask(taskId, { success: false, error: errorMsg }, false);
650
+ return {
651
+ content: [
652
+ {
653
+ type: 'text',
654
+ text: `❌ **Provider Error**\n\n${errorMsg}\n\nAvailable providers: ${this.providerBridgeService.listAvailableProviders().join(', ')}`,
655
+ },
656
+ ],
657
+ success: false,
658
+ agent: agentId,
659
+ provider: 'none',
660
+ error: errorMsg,
661
+ taskId,
662
+ readOnlyMode: true,
663
+ readOnly: true,
664
+ };
665
+ }
666
+ const resolvedProviderName = providerResolution.provider.name;
667
+ if (args.provider) {
668
+ this.taskManagementService.addTaskLog(taskId, {
669
+ level: 'info',
670
+ message: `Using CLI-specified provider: ${args.provider} (resolved to ${resolvedProviderName})`
671
+ });
672
+ }
673
+ else if (providerInput) {
674
+ this.taskManagementService.addTaskLog(taskId, {
675
+ level: 'info',
676
+ message: `Agent provider resolved to ${resolvedProviderName} (input: ${providerInput})`
677
+ });
467
678
  }
468
679
  else {
469
- provider = agent.provider || 'claude';
680
+ this.taskManagementService.addTaskLog(taskId, {
681
+ level: 'info',
682
+ message: `Using ProviderBridge fallback provider: ${resolvedProviderName}`,
683
+ });
470
684
  }
471
- const agentOptions = this.getOptionsForAgent(agent, 'query', provider);
472
- const modelToUse = model || agent.inline?.model;
685
+ const agentOptions = this.getOptionsForAgent(agent, 'query', resolvedProviderName);
686
+ const modelToUse = model || agent.inline?.model || providerResolution.defaultModel;
473
687
  const structuredPayload = await this.buildStructuredPayload({
474
688
  agentId,
475
- provider,
689
+ provider: resolvedProviderName,
476
690
  mode: 'query',
477
691
  prompt: fullPrompt,
478
692
  context,
@@ -480,17 +694,55 @@ ${query}
480
694
  platform: platform || 'cli',
481
695
  model: modelToUse,
482
696
  });
483
- response = await this.aiService.queryAI(fullPrompt, provider, {
484
- workingDirectory: workingDir,
485
- timeout: this.timeoutConfig.parallel,
486
- additionalArgs: agentOptions,
487
- taskId,
488
- model: modelToUse,
489
- agentId,
490
- securityKey,
491
- messages,
492
- pipedContext: structuredPayload,
493
- });
697
+ const runtimeMessages = this.toConversationMessages(messages);
698
+ let agentResult;
699
+ try {
700
+ agentResult = await runtimeResult.runtime.agent.query({
701
+ agentId,
702
+ prompt: fullPrompt,
703
+ context,
704
+ messages: runtimeMessages,
705
+ model: modelToUse,
706
+ options: {
707
+ workingDirectory: workingDir,
708
+ timeout: this.timeoutConfig.parallel,
709
+ additionalArgs: agentOptions,
710
+ taskId,
711
+ securityKey,
712
+ pipedContext: structuredPayload,
713
+ },
714
+ });
715
+ }
716
+ catch (error) {
717
+ const errorMsg = error instanceof Error ? error.message : 'Agent runtime query failed';
718
+ this.taskManagementService.addTaskLog(taskId, {
719
+ level: 'error',
720
+ message: `Agent runtime query failed: ${errorMsg}`,
721
+ });
722
+ this.taskManagementService.completeTask(taskId, { success: false, error: errorMsg }, false);
723
+ return {
724
+ content: [
725
+ {
726
+ type: 'text',
727
+ text: `❌ **Provider Error**\n\n${errorMsg}\n\nAvailable providers: ${this.providerBridgeService.listAvailableProviders().join(', ')}`,
728
+ },
729
+ ],
730
+ success: false,
731
+ agent: agentId,
732
+ provider: resolvedProviderName,
733
+ error: errorMsg,
734
+ taskId,
735
+ readOnlyMode: true,
736
+ readOnly: true,
737
+ };
738
+ }
739
+ const response = {
740
+ success: agentResult.success,
741
+ content: agentResult.content,
742
+ provider: agentResult.metadata?.provider ?? resolvedProviderName,
743
+ taskId: agentResult.metadata?.taskId ?? taskId,
744
+ error: agentResult.metadata?.error,
745
+ };
494
746
  this.taskManagementService.addTaskLog(taskId, { level: 'info', message: `Query completed. Success: ${response.success}` });
495
747
  this.taskManagementService.completeTask(taskId, response, response.success);
496
748
  const responseText = response.success
@@ -624,34 +876,59 @@ Please check the agent ID and try again.`
624
876
  }
625
877
  }
626
878
  const workingDir = projectPath || agent.workingDirectory || './';
627
- let systemPrompt = agent.systemPrompt || agent.description || `You are an expert ${agentId}.`;
628
879
  const securityKey = this.generateSecurityKey();
629
- if (systemPrompt) {
630
- const { processDocumentTemplate } = await Promise.resolve().then(() => __importStar(require('./utils/template-processor')));
631
- const contextMessages = messages && messages.length > 0 ? messages.slice(0, -1) : [];
632
- const templateContext = {
633
- env: process.env,
634
- agent: {
635
- id: agent.id,
636
- name: agent.name || agent.id,
637
- provider: (Array.isArray(agent.provider) ? agent.provider[0] : agent.provider) || 'claude',
638
- model: model || agent.inline?.model,
639
- workingDirectory: workingDir,
640
- },
641
- mode: 'execute',
642
- messages: contextMessages,
643
- platform: platform,
644
- tools: this.buildToolsContext(),
645
- vars: {
646
- security_key: securityKey,
880
+ const contextMessages = messages && messages.length > 0 ? messages.slice(0, -1) : [];
881
+ const templateContext = {
882
+ user_input: task,
883
+ messages: contextMessages,
884
+ agent: {
885
+ id: agent.id,
886
+ name: agent.name || agent.id,
887
+ provider: (Array.isArray(agent.provider) ? agent.provider[0] : agent.provider) || 'claude',
888
+ model: model || agent.inline?.model,
889
+ workingDirectory: workingDir,
890
+ inline: {
891
+ prompt: agent.inline?.prompt || agent.inline?.system_prompt || agent.systemPrompt || '',
647
892
  },
648
- };
649
- systemPrompt = await processDocumentTemplate(systemPrompt, this.documentLoaderService, templateContext);
650
- }
651
- systemPrompt += `
893
+ specialties: agent.specialties,
894
+ capabilities: agent.capabilities,
895
+ description: agent.description,
896
+ },
897
+ documents: {},
898
+ vars: {
899
+ security_key: securityKey,
900
+ },
901
+ props: {},
902
+ mode: 'execute',
903
+ platform: platform,
904
+ env: process.env,
905
+ tools: this.buildToolsContext(),
906
+ };
907
+ let systemPrompt = await this.processAgentSystemPrompt(agent, templateContext);
908
+ if (process.env.CREWX_APPEND_LEGACY === 'true') {
909
+ this.logger.debug('[WBS-14] Legacy append mode enabled (execute)', {
910
+ agentId: agent.id,
911
+ layoutId: typeof agent.inline?.layout === 'string'
912
+ ? agent.inline?.layout
913
+ : agent.inline?.layout?.id ?? 'crewx/default',
914
+ });
915
+ systemPrompt += `
652
916
  Specialties: ${agent.specialties?.join(', ') || 'General'}
653
917
  Capabilities: ${agent.capabilities?.join(', ') || 'Implementation'}
654
918
  Working Directory: ${workingDir}`;
919
+ }
920
+ else if (process.env.CREWX_WBS14_TELEMETRY === 'true') {
921
+ this.logger.debug('[WBS-14] Metadata delegated to layout (execute mode)', {
922
+ agentId: agent.id,
923
+ hasLayout: Boolean(agent.inline?.layout),
924
+ layoutId: typeof agent.inline?.layout === 'string'
925
+ ? agent.inline?.layout
926
+ : agent.inline?.layout?.id ?? 'crewx/default',
927
+ specialtiesCount: agent.specialties?.length ?? 0,
928
+ capabilitiesCount: agent.capabilities?.length ?? 0,
929
+ workingDirectory: workingDir,
930
+ });
931
+ }
655
932
  const fullPrompt = context
656
933
  ? `${systemPrompt}
657
934
  ${context}
@@ -662,26 +939,74 @@ Task: ${task}
662
939
 
663
940
  Task: ${task}
664
941
  `;
665
- let response;
666
- let provider;
667
- if (Array.isArray(agent.provider)) {
668
- if (agent.inline?.model || model) {
669
- provider = agent.provider[0] || 'claude';
670
- }
671
- else {
672
- provider = await this.getAvailableProvider(agent.provider);
673
- this.taskManagementService.addTaskLog(taskId, { level: 'info', message: `Using fallback provider: ${provider}` });
674
- }
942
+ let runtimeResult;
943
+ let providerResolution;
944
+ let providerInput;
945
+ if (args.provider) {
946
+ providerInput = args.provider;
947
+ }
948
+ else if (Array.isArray(agent.provider)) {
949
+ providerInput = await this.getAvailableProvider(agent.provider);
950
+ }
951
+ else if (typeof agent.provider === 'string' && agent.provider.trim().length > 0) {
952
+ providerInput = agent.provider;
953
+ }
954
+ try {
955
+ runtimeResult = await this.providerBridgeService.createAgentRuntime({
956
+ provider: providerInput,
957
+ defaultAgentId: agentId,
958
+ validAgents: agents.map(a => a.id),
959
+ enableCallStack: true,
960
+ });
961
+ providerResolution = runtimeResult.resolution;
962
+ }
963
+ catch (error) {
964
+ const errorMsg = error instanceof Error ? error.message : 'Unknown provider error';
965
+ this.taskManagementService.addTaskLog(taskId, {
966
+ level: 'error',
967
+ message: `Provider resolution failed: ${errorMsg}`,
968
+ });
969
+ this.taskManagementService.completeTask(taskId, { success: false, error: errorMsg }, false);
970
+ return {
971
+ content: [
972
+ {
973
+ type: 'text',
974
+ text: `❌ **Provider Error**\n\n${errorMsg}\n\nAvailable providers: ${this.providerBridgeService.listAvailableProviders().join(', ')}`,
975
+ },
976
+ ],
977
+ success: false,
978
+ agent: agentId,
979
+ provider: 'none',
980
+ error: errorMsg,
981
+ taskId,
982
+ readOnlyMode: false,
983
+ readOnly: false,
984
+ };
985
+ }
986
+ const resolvedProviderName = providerResolution.provider.name;
987
+ if (args.provider) {
988
+ this.taskManagementService.addTaskLog(taskId, {
989
+ level: 'info',
990
+ message: `Using CLI-specified provider: ${args.provider} (resolved to ${resolvedProviderName})`
991
+ });
992
+ }
993
+ else if (providerInput) {
994
+ this.taskManagementService.addTaskLog(taskId, {
995
+ level: 'info',
996
+ message: `Agent provider resolved to ${resolvedProviderName} (input: ${providerInput})`
997
+ });
675
998
  }
676
999
  else {
677
- provider = agent.provider || 'claude';
1000
+ this.taskManagementService.addTaskLog(taskId, {
1001
+ level: 'info',
1002
+ message: `Using ProviderBridge fallback provider: ${resolvedProviderName}`,
1003
+ });
678
1004
  }
679
- this.taskManagementService.addTaskLog(taskId, { level: 'info', message: `Using provider: ${provider}` });
680
- const agentOptions = this.getOptionsForAgent(agent, 'execute', provider);
681
- const modelToUse = model || agent.inline?.model;
1005
+ const agentOptions = this.getOptionsForAgent(agent, 'execute', resolvedProviderName);
1006
+ const modelToUse = model || agent.inline?.model || providerResolution.defaultModel;
682
1007
  const structuredPayload = await this.buildStructuredPayload({
683
1008
  agentId,
684
- provider,
1009
+ provider: resolvedProviderName,
685
1010
  mode: 'execute',
686
1011
  prompt: fullPrompt,
687
1012
  context,
@@ -689,16 +1014,55 @@ Task: ${task}
689
1014
  platform: platform || 'cli',
690
1015
  model: modelToUse,
691
1016
  });
692
- response = await this.aiService.executeAI(fullPrompt, provider, {
693
- workingDirectory: workingDir,
694
- timeout: 1200000,
695
- taskId: taskId,
696
- additionalArgs: agentOptions,
697
- model: modelToUse,
698
- agentId,
699
- messages,
700
- pipedContext: structuredPayload,
701
- });
1017
+ const runtimeMessages = this.toConversationMessages(messages);
1018
+ let agentResult;
1019
+ try {
1020
+ agentResult = await runtimeResult.runtime.agent.execute({
1021
+ agentId,
1022
+ prompt: fullPrompt,
1023
+ context,
1024
+ messages: runtimeMessages,
1025
+ model: modelToUse,
1026
+ options: {
1027
+ workingDirectory: workingDir,
1028
+ timeout: 1200000,
1029
+ additionalArgs: agentOptions,
1030
+ taskId,
1031
+ pipedContext: structuredPayload,
1032
+ securityKey,
1033
+ },
1034
+ });
1035
+ }
1036
+ catch (error) {
1037
+ const errorMsg = error instanceof Error ? error.message : 'Agent runtime execution failed';
1038
+ this.taskManagementService.addTaskLog(taskId, {
1039
+ level: 'error',
1040
+ message: `Agent runtime execution failed: ${errorMsg}`,
1041
+ });
1042
+ this.taskManagementService.completeTask(taskId, { success: false, error: errorMsg }, false);
1043
+ return {
1044
+ content: [
1045
+ {
1046
+ type: 'text',
1047
+ text: `❌ **Provider Error**\n\n${errorMsg}\n\nAvailable providers: ${this.providerBridgeService.listAvailableProviders().join(', ')}`,
1048
+ },
1049
+ ],
1050
+ success: false,
1051
+ agent: agentId,
1052
+ provider: resolvedProviderName,
1053
+ error: errorMsg,
1054
+ taskId,
1055
+ readOnlyMode: false,
1056
+ readOnly: false,
1057
+ };
1058
+ }
1059
+ const response = {
1060
+ success: agentResult.success,
1061
+ content: agentResult.content,
1062
+ provider: agentResult.metadata?.provider ?? resolvedProviderName,
1063
+ taskId: agentResult.metadata?.taskId ?? taskId,
1064
+ error: agentResult.metadata?.error,
1065
+ };
702
1066
  this.taskManagementService.addTaskLog(taskId, { level: 'info', message: `Execution completed. Success: ${response.success}` });
703
1067
  this.taskManagementService.completeTask(taskId, response, response.success);
704
1068
  const responseText = response.success ? response.content : `❌ Execution Failed: ${response.error}`;
@@ -770,6 +1134,41 @@ Task: ${task}
770
1134
  readOnly,
771
1135
  };
772
1136
  }
1137
+ toConversationMessages(messages) {
1138
+ if (!messages || messages.length === 0) {
1139
+ return [];
1140
+ }
1141
+ return messages.map((message, index) => {
1142
+ const metadata = message.metadata ?? {};
1143
+ const rawTimestamp = metadata.timestamp;
1144
+ let timestamp;
1145
+ if (rawTimestamp instanceof Date) {
1146
+ timestamp = rawTimestamp;
1147
+ }
1148
+ else if (typeof rawTimestamp === 'number') {
1149
+ timestamp = new Date(rawTimestamp);
1150
+ }
1151
+ else if (typeof rawTimestamp === 'string') {
1152
+ const parsed = new Date(rawTimestamp);
1153
+ timestamp = Number.isNaN(parsed.getTime()) ? new Date() : parsed;
1154
+ }
1155
+ else {
1156
+ timestamp = new Date();
1157
+ }
1158
+ return {
1159
+ id: typeof metadata.id === 'string' ? metadata.id : `cli-msg-${index}`,
1160
+ userId: typeof metadata.userId === 'string'
1161
+ ? metadata.userId
1162
+ : message.isAssistant
1163
+ ? 'assistant'
1164
+ : 'user',
1165
+ text: message.text,
1166
+ timestamp,
1167
+ isAssistant: message.isAssistant,
1168
+ metadata: metadata,
1169
+ };
1170
+ });
1171
+ }
773
1172
  getOptionsForAgent(agent, mode, provider) {
774
1173
  try {
775
1174
  if (agent.options && typeof agent.options === 'object' && !Array.isArray(agent.options)) {
@@ -1446,6 +1845,8 @@ __decorate([
1446
1845
  ], CrewXTool.prototype, "clearAllLogs", null);
1447
1846
  exports.CrewXTool = CrewXTool = CrewXTool_1 = __decorate([
1448
1847
  (0, common_1.Injectable)(),
1848
+ __param(12, (0, common_1.Inject)('LAYOUT_LOADER')),
1849
+ __param(13, (0, common_1.Inject)('LAYOUT_RENDERER')),
1449
1850
  __metadata("design:paramtypes", [ai_service_1.AIService,
1450
1851
  ai_provider_service_1.AIProviderService,
1451
1852
  project_service_1.ProjectService,
@@ -1456,6 +1857,9 @@ exports.CrewXTool = CrewXTool = CrewXTool_1 = __decorate([
1456
1857
  document_loader_service_1.DocumentLoaderService,
1457
1858
  tool_call_service_1.ToolCallService,
1458
1859
  agent_loader_service_1.AgentLoaderService,
1459
- remote_agent_service_1.RemoteAgentService])
1860
+ remote_agent_service_1.RemoteAgentService,
1861
+ provider_bridge_service_1.ProviderBridgeService,
1862
+ crewx_sdk_1.LayoutLoader,
1863
+ crewx_sdk_1.LayoutRenderer])
1460
1864
  ], CrewXTool);
1461
1865
  //# sourceMappingURL=crewx.tool.js.map