aiexecode 1.0.94 → 1.0.127
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.
Potentially problematic release.
This version of aiexecode might be problematic. Click here for more details.
- package/README.md +198 -88
- package/index.js +310 -86
- package/mcp-agent-lib/src/mcp_message_logger.js +17 -16
- package/package.json +4 -4
- package/payload_viewer/out/404/index.html +1 -1
- package/payload_viewer/out/404.html +1 -1
- package/payload_viewer/out/_next/static/chunks/{37d0cd2587a38f79.js → b6c0459f3789d25c.js} +1 -1
- package/payload_viewer/out/_next/static/chunks/b75131b58f8ca46a.css +3 -0
- package/payload_viewer/out/index.html +1 -1
- package/payload_viewer/out/index.txt +3 -3
- package/payload_viewer/web_server.js +361 -0
- package/prompts/completion_judge.txt +4 -0
- package/prompts/orchestrator.txt +116 -3
- package/src/LLMClient/client.js +401 -18
- package/src/LLMClient/converters/responses-to-claude.js +67 -18
- package/src/LLMClient/converters/responses-to-zai.js +667 -0
- package/src/LLMClient/errors.js +30 -4
- package/src/LLMClient/index.js +5 -0
- package/src/ai_based/completion_judge.js +263 -186
- package/src/ai_based/orchestrator.js +171 -35
- package/src/commands/agents.js +70 -0
- package/src/commands/apikey.js +1 -1
- package/src/commands/bg.js +129 -0
- package/src/commands/commands.js +51 -0
- package/src/commands/debug.js +52 -0
- package/src/commands/help.js +11 -1
- package/src/commands/model.js +42 -7
- package/src/commands/reasoning_effort.js +2 -2
- package/src/commands/skills.js +46 -0
- package/src/config/ai_models.js +106 -6
- package/src/config/constants.js +71 -0
- package/src/config/feature_flags.js +6 -7
- package/src/frontend/App.js +108 -1
- package/src/frontend/components/AutocompleteMenu.js +7 -1
- package/src/frontend/components/BackgroundProcessList.js +175 -0
- package/src/frontend/components/ConversationItem.js +26 -10
- package/src/frontend/components/CurrentModelView.js +2 -2
- package/src/frontend/components/HelpView.js +106 -2
- package/src/frontend/components/Input.js +33 -11
- package/src/frontend/components/ModelListView.js +1 -1
- package/src/frontend/components/SetupWizard.js +51 -8
- package/src/frontend/hooks/useFileCompletion.js +467 -0
- package/src/frontend/utils/toolUIFormatter.js +261 -0
- package/src/system/agents_loader.js +289 -0
- package/src/system/ai_request.js +156 -12
- package/src/system/background_process.js +317 -0
- package/src/system/code_executer.js +496 -56
- package/src/system/command_parser.js +33 -3
- package/src/system/conversation_state.js +265 -0
- package/src/system/conversation_trimmer.js +132 -0
- package/src/system/custom_command_loader.js +386 -0
- package/src/system/file_integrity.js +73 -10
- package/src/system/log.js +10 -2
- package/src/system/output_helper.js +52 -9
- package/src/system/session.js +213 -58
- package/src/system/session_memory.js +30 -2
- package/src/system/skill_loader.js +318 -0
- package/src/system/system_info.js +254 -40
- package/src/system/tool_approval.js +10 -0
- package/src/system/tool_registry.js +15 -1
- package/src/system/ui_events.js +11 -0
- package/src/tools/code_editor.js +16 -10
- package/src/tools/file_reader.js +66 -9
- package/src/tools/glob.js +0 -3
- package/src/tools/ripgrep.js +5 -7
- package/src/tools/skill_tool.js +122 -0
- package/src/tools/web_downloader.js +0 -3
- package/src/util/clone.js +174 -0
- package/src/util/config.js +55 -2
- package/src/util/config_migration.js +174 -0
- package/src/util/debug_log.js +8 -2
- package/src/util/exit_handler.js +8 -0
- package/src/util/file_reference_parser.js +132 -0
- package/src/util/path_validator.js +178 -0
- package/src/util/prompt_loader.js +91 -1
- package/src/util/safe_fs.js +66 -3
- package/payload_viewer/out/_next/static/chunks/ecd2072ebf41611f.css +0 -3
- /package/payload_viewer/out/_next/static/{wkEKh6i9XPSyP6rjDRvHn → 42iEoi-1o5MxNIZ1SWSvV}/_buildManifest.js +0 -0
- /package/payload_viewer/out/_next/static/{wkEKh6i9XPSyP6rjDRvHn → 42iEoi-1o5MxNIZ1SWSvV}/_clientMiddlewareManifest.json +0 -0
- /package/payload_viewer/out/_next/static/{wkEKh6i9XPSyP6rjDRvHn → 42iEoi-1o5MxNIZ1SWSvV}/_ssgManifest.js +0 -0
|
@@ -3,6 +3,7 @@ import path from 'path';
|
|
|
3
3
|
import fs from 'fs';
|
|
4
4
|
import { fileURLToPath } from 'url';
|
|
5
5
|
import OpenAI from 'openai';
|
|
6
|
+
import Anthropic from '@anthropic-ai/sdk';
|
|
6
7
|
function consolelog() { }
|
|
7
8
|
|
|
8
9
|
const __filename = fileURLToPath(import.meta.url);
|
|
@@ -48,6 +49,46 @@ if (openaiApiKey) {
|
|
|
48
49
|
consolelog(' Checked: process.env.OPENAI_API_KEY and ~/.aiexe/settings.json');
|
|
49
50
|
}
|
|
50
51
|
|
|
52
|
+
// Initialize Z.AI client (Anthropic SDK with Z.AI base URL)
|
|
53
|
+
let zaiClient = null;
|
|
54
|
+
const zaiApiKey = process.env.ZAI_API_KEY || aiAgentSettings.API_KEY;
|
|
55
|
+
const ZAI_BASE_URL = 'https://api.z.ai/api/anthropic';
|
|
56
|
+
|
|
57
|
+
// Check if API key is Z.AI format (32-char hex + '.' + 16-char alphanumeric)
|
|
58
|
+
function isZaiApiKey(apiKey) {
|
|
59
|
+
if (!apiKey || typeof apiKey !== 'string') return false;
|
|
60
|
+
return /^[a-f0-9]{32}\.[A-Za-z0-9]{16}$/.test(apiKey);
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
if (zaiApiKey && isZaiApiKey(zaiApiKey)) {
|
|
64
|
+
zaiClient = new Anthropic({
|
|
65
|
+
apiKey: zaiApiKey,
|
|
66
|
+
baseURL: ZAI_BASE_URL,
|
|
67
|
+
});
|
|
68
|
+
consolelog('✅ Z.AI client initialized (Anthropic SDK with Z.AI base URL)');
|
|
69
|
+
} else {
|
|
70
|
+
consolelog('⚠️ Z.AI API key not found or invalid format - Z.AI testing will return mock responses');
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
// Initialize Anthropic client
|
|
74
|
+
let anthropicClient = null;
|
|
75
|
+
const anthropicApiKey = process.env.ANTHROPIC_API_KEY || aiAgentSettings.ANTHROPIC_API_KEY;
|
|
76
|
+
|
|
77
|
+
// Check if API key is Anthropic format (sk-ant-...)
|
|
78
|
+
function isAnthropicApiKey(apiKey) {
|
|
79
|
+
if (!apiKey || typeof apiKey !== 'string') return false;
|
|
80
|
+
return apiKey.startsWith('sk-ant-');
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
if (anthropicApiKey && isAnthropicApiKey(anthropicApiKey)) {
|
|
84
|
+
anthropicClient = new Anthropic({
|
|
85
|
+
apiKey: anthropicApiKey,
|
|
86
|
+
});
|
|
87
|
+
consolelog('✅ Anthropic client initialized');
|
|
88
|
+
} else {
|
|
89
|
+
consolelog('⚠️ Anthropic API key not found or invalid format - Anthropic testing will return mock responses');
|
|
90
|
+
}
|
|
91
|
+
|
|
51
92
|
|
|
52
93
|
// ID generation function
|
|
53
94
|
function generateId() {
|
|
@@ -420,6 +461,326 @@ function startWebServer(port = 3300) {
|
|
|
420
461
|
}
|
|
421
462
|
});
|
|
422
463
|
|
|
464
|
+
// Anthropic API test endpoint
|
|
465
|
+
app.post('/api/test-anthropic', async (req, res) => {
|
|
466
|
+
try {
|
|
467
|
+
const payload = req.body;
|
|
468
|
+
|
|
469
|
+
if (anthropicClient && anthropicApiKey && isAnthropicApiKey(anthropicApiKey)) {
|
|
470
|
+
// Convert Responses API format to Anthropic Messages API format if needed
|
|
471
|
+
let anthropicPayload = { ...payload };
|
|
472
|
+
|
|
473
|
+
// If payload uses Responses API format (input array), convert to messages
|
|
474
|
+
if (payload.input && Array.isArray(payload.input)) {
|
|
475
|
+
const messages = [];
|
|
476
|
+
let systemMessage = null;
|
|
477
|
+
|
|
478
|
+
for (const item of payload.input) {
|
|
479
|
+
if (item.role === 'system') {
|
|
480
|
+
if (Array.isArray(item.content)) {
|
|
481
|
+
systemMessage = item.content.map(c => c.text || c).join('\n');
|
|
482
|
+
} else if (typeof item.content === 'string') {
|
|
483
|
+
systemMessage = item.content;
|
|
484
|
+
}
|
|
485
|
+
} else if (item.role === 'user' || item.role === 'assistant') {
|
|
486
|
+
let content;
|
|
487
|
+
if (Array.isArray(item.content)) {
|
|
488
|
+
content = item.content.map(c => ({
|
|
489
|
+
type: 'text',
|
|
490
|
+
text: c.text || c
|
|
491
|
+
}));
|
|
492
|
+
} else {
|
|
493
|
+
content = [{ type: 'text', text: item.content || '' }];
|
|
494
|
+
}
|
|
495
|
+
messages.push({ role: item.role, content });
|
|
496
|
+
}
|
|
497
|
+
}
|
|
498
|
+
|
|
499
|
+
anthropicPayload = {
|
|
500
|
+
model: payload.model || 'claude-3-haiku-20240307',
|
|
501
|
+
max_tokens: payload.max_output_tokens || payload.max_tokens || 4096,
|
|
502
|
+
messages: messages,
|
|
503
|
+
};
|
|
504
|
+
|
|
505
|
+
if (systemMessage) {
|
|
506
|
+
anthropicPayload.system = systemMessage;
|
|
507
|
+
}
|
|
508
|
+
}
|
|
509
|
+
|
|
510
|
+
// Ensure required fields
|
|
511
|
+
if (!anthropicPayload.model) anthropicPayload.model = 'claude-3-haiku-20240307';
|
|
512
|
+
if (!anthropicPayload.max_tokens) anthropicPayload.max_tokens = 4096;
|
|
513
|
+
|
|
514
|
+
// Make the API call
|
|
515
|
+
const response = await anthropicClient.messages.create(anthropicPayload);
|
|
516
|
+
|
|
517
|
+
// Convert Anthropic response to Responses API format
|
|
518
|
+
const output = [];
|
|
519
|
+
let outputText = '';
|
|
520
|
+
|
|
521
|
+
if (response.content && Array.isArray(response.content)) {
|
|
522
|
+
for (const block of response.content) {
|
|
523
|
+
if (block.type === 'text') {
|
|
524
|
+
outputText += block.text;
|
|
525
|
+
} else if (block.type === 'tool_use') {
|
|
526
|
+
output.push({
|
|
527
|
+
type: 'function_call',
|
|
528
|
+
id: block.id,
|
|
529
|
+
call_id: block.id,
|
|
530
|
+
name: block.name,
|
|
531
|
+
arguments: JSON.stringify(block.input)
|
|
532
|
+
});
|
|
533
|
+
}
|
|
534
|
+
}
|
|
535
|
+
}
|
|
536
|
+
|
|
537
|
+
if (outputText) {
|
|
538
|
+
output.unshift({
|
|
539
|
+
type: 'message',
|
|
540
|
+
id: `msg_${generateId()}`,
|
|
541
|
+
status: 'completed',
|
|
542
|
+
role: 'assistant',
|
|
543
|
+
content: [{
|
|
544
|
+
type: 'output_text',
|
|
545
|
+
text: outputText
|
|
546
|
+
}]
|
|
547
|
+
});
|
|
548
|
+
}
|
|
549
|
+
|
|
550
|
+
const convertedResponse = {
|
|
551
|
+
id: response.id,
|
|
552
|
+
object: 'response',
|
|
553
|
+
created_at: Math.floor(Date.now() / 1000),
|
|
554
|
+
status: response.stop_reason === 'end_turn' ? 'completed' : 'incomplete',
|
|
555
|
+
model: response.model,
|
|
556
|
+
provider: 'anthropic',
|
|
557
|
+
output: output,
|
|
558
|
+
usage: {
|
|
559
|
+
input_tokens: response.usage?.input_tokens || 0,
|
|
560
|
+
output_tokens: response.usage?.output_tokens || 0,
|
|
561
|
+
total_tokens: (response.usage?.input_tokens || 0) + (response.usage?.output_tokens || 0),
|
|
562
|
+
cache_creation_input_tokens: response.usage?.cache_creation_input_tokens,
|
|
563
|
+
cache_read_input_tokens: response.usage?.cache_read_input_tokens
|
|
564
|
+
},
|
|
565
|
+
stop_reason: response.stop_reason
|
|
566
|
+
};
|
|
567
|
+
|
|
568
|
+
res.json({
|
|
569
|
+
success: true,
|
|
570
|
+
provider: 'anthropic',
|
|
571
|
+
status: 200,
|
|
572
|
+
data: convertedResponse,
|
|
573
|
+
originalPayload: payload,
|
|
574
|
+
convertedPayload: anthropicPayload,
|
|
575
|
+
rawResponse: response
|
|
576
|
+
});
|
|
577
|
+
} else {
|
|
578
|
+
// Mock response when API key is not available
|
|
579
|
+
res.json({
|
|
580
|
+
success: false,
|
|
581
|
+
provider: 'anthropic',
|
|
582
|
+
error: 'Anthropic API key not found or invalid format',
|
|
583
|
+
hint: 'Anthropic API key format: sk-ant-...',
|
|
584
|
+
mockResponse: {
|
|
585
|
+
taskName: "api_test_RES",
|
|
586
|
+
timestamp: new Date().toISOString(),
|
|
587
|
+
data: {
|
|
588
|
+
id: `resp_${generateId()}`,
|
|
589
|
+
object: "response",
|
|
590
|
+
created_at: Math.floor(Date.now() / 1000),
|
|
591
|
+
status: "completed",
|
|
592
|
+
model: payload.model || 'claude-3-haiku-20240307',
|
|
593
|
+
provider: 'anthropic',
|
|
594
|
+
output: [{
|
|
595
|
+
id: `msg_${generateId()}`,
|
|
596
|
+
type: "message",
|
|
597
|
+
status: "completed",
|
|
598
|
+
content: [{
|
|
599
|
+
type: "output_text",
|
|
600
|
+
text: 'This is a mock response. Set a valid Anthropic API key to get real responses.'
|
|
601
|
+
}],
|
|
602
|
+
role: "assistant"
|
|
603
|
+
}],
|
|
604
|
+
usage: {
|
|
605
|
+
input_tokens: 10,
|
|
606
|
+
output_tokens: 15,
|
|
607
|
+
total_tokens: 25
|
|
608
|
+
}
|
|
609
|
+
}
|
|
610
|
+
},
|
|
611
|
+
originalPayload: payload
|
|
612
|
+
});
|
|
613
|
+
}
|
|
614
|
+
} catch (error) {
|
|
615
|
+
res.status(500).json({
|
|
616
|
+
success: false,
|
|
617
|
+
provider: 'anthropic',
|
|
618
|
+
error: error.message,
|
|
619
|
+
originalPayload: req.body
|
|
620
|
+
});
|
|
621
|
+
}
|
|
622
|
+
});
|
|
623
|
+
|
|
624
|
+
// Z.AI (GLM) API test endpoint - Uses Anthropic SDK with Z.AI base URL
|
|
625
|
+
app.post('/api/test-zai', async (req, res) => {
|
|
626
|
+
try {
|
|
627
|
+
const payload = req.body;
|
|
628
|
+
|
|
629
|
+
if (zaiClient && zaiApiKey && isZaiApiKey(zaiApiKey)) {
|
|
630
|
+
// Convert Responses API format to Anthropic Messages API format if needed
|
|
631
|
+
let zaiPayload = { ...payload };
|
|
632
|
+
|
|
633
|
+
// If payload uses Responses API format (input array), convert to messages
|
|
634
|
+
if (payload.input && Array.isArray(payload.input)) {
|
|
635
|
+
const messages = [];
|
|
636
|
+
let systemMessage = null;
|
|
637
|
+
|
|
638
|
+
for (const item of payload.input) {
|
|
639
|
+
if (item.role === 'system') {
|
|
640
|
+
// Extract system message content
|
|
641
|
+
if (Array.isArray(item.content)) {
|
|
642
|
+
systemMessage = item.content.map(c => c.text || c).join('\n');
|
|
643
|
+
} else if (typeof item.content === 'string') {
|
|
644
|
+
systemMessage = item.content;
|
|
645
|
+
}
|
|
646
|
+
} else if (item.role === 'user' || item.role === 'assistant') {
|
|
647
|
+
let content;
|
|
648
|
+
if (Array.isArray(item.content)) {
|
|
649
|
+
content = item.content.map(c => ({
|
|
650
|
+
type: 'text',
|
|
651
|
+
text: c.text || c
|
|
652
|
+
}));
|
|
653
|
+
} else {
|
|
654
|
+
content = [{ type: 'text', text: item.content || '' }];
|
|
655
|
+
}
|
|
656
|
+
messages.push({ role: item.role, content });
|
|
657
|
+
}
|
|
658
|
+
}
|
|
659
|
+
|
|
660
|
+
zaiPayload = {
|
|
661
|
+
model: payload.model || 'glm-4.5',
|
|
662
|
+
max_tokens: payload.max_output_tokens || payload.max_tokens || 8192,
|
|
663
|
+
messages: messages,
|
|
664
|
+
};
|
|
665
|
+
|
|
666
|
+
if (systemMessage) {
|
|
667
|
+
zaiPayload.system = systemMessage;
|
|
668
|
+
}
|
|
669
|
+
}
|
|
670
|
+
|
|
671
|
+
// Ensure required fields
|
|
672
|
+
if (!zaiPayload.model) zaiPayload.model = 'glm-4.5';
|
|
673
|
+
if (!zaiPayload.max_tokens) zaiPayload.max_tokens = 8192;
|
|
674
|
+
|
|
675
|
+
// Make the API call
|
|
676
|
+
const response = await zaiClient.messages.create(zaiPayload);
|
|
677
|
+
|
|
678
|
+
// Convert Anthropic response to Responses API format
|
|
679
|
+
const output = [];
|
|
680
|
+
let outputText = '';
|
|
681
|
+
|
|
682
|
+
if (response.content && Array.isArray(response.content)) {
|
|
683
|
+
for (const block of response.content) {
|
|
684
|
+
if (block.type === 'text') {
|
|
685
|
+
outputText += block.text;
|
|
686
|
+
} else if (block.type === 'tool_use') {
|
|
687
|
+
output.push({
|
|
688
|
+
type: 'function_call',
|
|
689
|
+
id: block.id,
|
|
690
|
+
call_id: block.id,
|
|
691
|
+
name: block.name,
|
|
692
|
+
arguments: JSON.stringify(block.input)
|
|
693
|
+
});
|
|
694
|
+
}
|
|
695
|
+
}
|
|
696
|
+
}
|
|
697
|
+
|
|
698
|
+
if (outputText) {
|
|
699
|
+
output.unshift({
|
|
700
|
+
type: 'message',
|
|
701
|
+
id: `msg_${generateId()}`,
|
|
702
|
+
status: 'completed',
|
|
703
|
+
role: 'assistant',
|
|
704
|
+
content: [{
|
|
705
|
+
type: 'output_text',
|
|
706
|
+
text: outputText
|
|
707
|
+
}]
|
|
708
|
+
});
|
|
709
|
+
}
|
|
710
|
+
|
|
711
|
+
const convertedResponse = {
|
|
712
|
+
id: response.id,
|
|
713
|
+
object: 'response',
|
|
714
|
+
created_at: Math.floor(Date.now() / 1000),
|
|
715
|
+
status: response.stop_reason === 'end_turn' ? 'completed' : 'incomplete',
|
|
716
|
+
model: response.model,
|
|
717
|
+
provider: 'zai',
|
|
718
|
+
output: output,
|
|
719
|
+
usage: {
|
|
720
|
+
input_tokens: response.usage?.input_tokens || 0,
|
|
721
|
+
output_tokens: response.usage?.output_tokens || 0,
|
|
722
|
+
total_tokens: (response.usage?.input_tokens || 0) + (response.usage?.output_tokens || 0),
|
|
723
|
+
cache_creation_input_tokens: response.usage?.cache_creation_input_tokens,
|
|
724
|
+
cache_read_input_tokens: response.usage?.cache_read_input_tokens
|
|
725
|
+
},
|
|
726
|
+
stop_reason: response.stop_reason
|
|
727
|
+
};
|
|
728
|
+
|
|
729
|
+
res.json({
|
|
730
|
+
success: true,
|
|
731
|
+
provider: 'zai',
|
|
732
|
+
status: 200,
|
|
733
|
+
data: convertedResponse,
|
|
734
|
+
originalPayload: payload,
|
|
735
|
+
convertedPayload: zaiPayload,
|
|
736
|
+
rawResponse: response
|
|
737
|
+
});
|
|
738
|
+
} else {
|
|
739
|
+
// Mock response when API key is not available
|
|
740
|
+
res.json({
|
|
741
|
+
success: false,
|
|
742
|
+
provider: 'zai',
|
|
743
|
+
error: 'Z.AI API key not found or invalid format',
|
|
744
|
+
hint: 'Z.AI API key format: 32-char hex + "." + 16-char alphanumeric',
|
|
745
|
+
mockResponse: {
|
|
746
|
+
taskName: "api_test_RES",
|
|
747
|
+
timestamp: new Date().toISOString(),
|
|
748
|
+
data: {
|
|
749
|
+
id: `resp_${generateId()}`,
|
|
750
|
+
object: "response",
|
|
751
|
+
created_at: Math.floor(Date.now() / 1000),
|
|
752
|
+
status: "completed",
|
|
753
|
+
model: payload.model || 'glm-4.5',
|
|
754
|
+
provider: 'zai',
|
|
755
|
+
output: [{
|
|
756
|
+
id: `msg_${generateId()}`,
|
|
757
|
+
type: "message",
|
|
758
|
+
status: "completed",
|
|
759
|
+
content: [{
|
|
760
|
+
type: "output_text",
|
|
761
|
+
text: 'This is a mock response. Set a valid Z.AI API key to get real responses.'
|
|
762
|
+
}],
|
|
763
|
+
role: "assistant"
|
|
764
|
+
}],
|
|
765
|
+
usage: {
|
|
766
|
+
input_tokens: 10,
|
|
767
|
+
output_tokens: 15,
|
|
768
|
+
total_tokens: 25
|
|
769
|
+
}
|
|
770
|
+
}
|
|
771
|
+
},
|
|
772
|
+
originalPayload: payload
|
|
773
|
+
});
|
|
774
|
+
}
|
|
775
|
+
} catch (error) {
|
|
776
|
+
res.status(500).json({
|
|
777
|
+
success: false,
|
|
778
|
+
provider: 'zai',
|
|
779
|
+
error: error.message,
|
|
780
|
+
originalPayload: req.body
|
|
781
|
+
});
|
|
782
|
+
}
|
|
783
|
+
});
|
|
423
784
|
|
|
424
785
|
// Health check endpoint
|
|
425
786
|
app.get('/api/health', (req, res) => {
|
|
@@ -15,6 +15,7 @@ You have access to the full conversation history between the orchestrator and th
|
|
|
15
15
|
**CORE PRINCIPLE**: Focus STRICTLY on whether the ESSENTIAL requirements requested by the user have been fulfilled. The agent should NEVER perform optional enhancements beyond the user's explicit request.
|
|
16
16
|
|
|
17
17
|
### Mission is COMPLETE (should_complete: true) when:
|
|
18
|
+
- **The request cannot be fulfilled as stated**: The assistant clearly explains that the literal request is impossible and why. Do NOT continue pursuing an unfulfillable goal.
|
|
18
19
|
- **All essential requirements from the user's original request have been satisfied**
|
|
19
20
|
- The assistant explicitly states the task is finished/complete/done
|
|
20
21
|
- The assistant provides final results or deliverables that satisfy the original mission's core requirements
|
|
@@ -31,6 +32,9 @@ You have access to the full conversation history between the orchestrator and th
|
|
|
31
32
|
- The assistant's message is incomplete or cut off
|
|
32
33
|
- The message is just status updates without clear completion signals
|
|
33
34
|
- **There are mandatory next steps required to fulfill the user's core request**
|
|
35
|
+
- **The assistant is seeking permission, confirmation, or approval before taking action**
|
|
36
|
+
- **The assistant offers to do something rather than just doing it** (e.g., "Would you like me to...", "Should I...", "Do you want me to...", "Can I...")
|
|
37
|
+
- **The assistant's response implies waiting for user decision before proceeding with work**
|
|
34
38
|
|
|
35
39
|
### Key Distinction:
|
|
36
40
|
- **Essential Requirements**: ONLY the core functionality, features, or fixes explicitly requested by the user
|
package/prompts/orchestrator.txt
CHANGED
|
@@ -47,6 +47,21 @@ NEVER ASK USER:
|
|
|
47
47
|
- Permission to continue
|
|
48
48
|
- Technical decisions
|
|
49
49
|
|
|
50
|
+
# Understanding request feasibility
|
|
51
|
+
|
|
52
|
+
Before attempting any action, assess whether the request is actually achievable:
|
|
53
|
+
|
|
54
|
+
1. **Literal interpretation first**: Understand what the user literally asked for
|
|
55
|
+
2. **Feasibility check**: Can this request actually be fulfilled as stated?
|
|
56
|
+
3. **No silent reinterpretation**: If the literal request is impossible, do NOT silently substitute it with something "related" or "similar"
|
|
57
|
+
|
|
58
|
+
When a request cannot be fulfilled as stated:
|
|
59
|
+
- Clearly explain why it cannot be done
|
|
60
|
+
- Ask for clarification or suggest what you CAN do
|
|
61
|
+
- Do NOT attempt workarounds that don't address the actual request
|
|
62
|
+
|
|
63
|
+
Principle: Honesty about limitations is more valuable than creative reinterpretation that misses the point.
|
|
64
|
+
|
|
50
65
|
# Understanding user intent
|
|
51
66
|
|
|
52
67
|
Distinguish between conversation and work:
|
|
@@ -379,7 +394,33 @@ Use for: Finding code by content, exploring codebases, locating specific impleme
|
|
|
379
394
|
|
|
380
395
|
### bash
|
|
381
396
|
|
|
382
|
-
Purpose: Execute shell commands
|
|
397
|
+
Purpose: Execute shell commands (for terminal operations ONLY)
|
|
398
|
+
|
|
399
|
+
**CRITICAL - Use Specialized Tools Instead of Bash:**
|
|
400
|
+
|
|
401
|
+
NEVER use bash for these operations - use the dedicated tools:
|
|
402
|
+
|
|
403
|
+
| Operation | WRONG (bash) | CORRECT (dedicated tool) |
|
|
404
|
+
|-----------|--------------|--------------------------|
|
|
405
|
+
| Read files | `cat file.js` | `read_file({ filePath: "file.js" })` |
|
|
406
|
+
| Read file sections | `head -100 file.js` | `read_file_range({ filePath, startLine, endLine })` |
|
|
407
|
+
| Search content | `grep -r "pattern" .` | `ripgrep({ pattern: "pattern" })` |
|
|
408
|
+
| Find files | `find . -name "*.js"` | `glob_search({ pattern: "**/*.js" })` |
|
|
409
|
+
| Edit files | `sed -i 's/old/new/' file` | `edit_file_replace({ file_path, old_string, new_string })` |
|
|
410
|
+
| Write files | `echo "content" > file` | `write_file({ file_path, content })` |
|
|
411
|
+
|
|
412
|
+
**Why dedicated tools are mandatory:**
|
|
413
|
+
- bash output is truncated to 8000 chars - long files get cut off
|
|
414
|
+
- Dedicated tools have proper error handling and formatting
|
|
415
|
+
- Dedicated tools integrate with file integrity tracking
|
|
416
|
+
- Dedicated tools display results properly in UI
|
|
417
|
+
|
|
418
|
+
**When to use bash:**
|
|
419
|
+
- git commands: `git status`, `git commit`, `git push`
|
|
420
|
+
- Package management: `npm install`, `pip install`
|
|
421
|
+
- Running scripts: `npm test`, `python script.py`
|
|
422
|
+
- Directory operations: `mkdir`, `rm -rf`, `mv`, `cp`
|
|
423
|
+
- System commands: `chmod`, `chown`, `which`
|
|
383
424
|
|
|
384
425
|
Usage notes:
|
|
385
426
|
- Output limits: stdout 8000 chars, stderr 4000 chars
|
|
@@ -813,10 +854,43 @@ Match the user's language:
|
|
|
813
854
|
|
|
814
855
|
## Tool usage
|
|
815
856
|
|
|
816
|
-
-
|
|
817
|
-
|
|
857
|
+
**MANDATORY - Specialized Tools Over Bash:**
|
|
858
|
+
|
|
859
|
+
This is NOT optional. You MUST use dedicated tools for these operations:
|
|
860
|
+
|
|
861
|
+
| Task | NEVER Use | ALWAYS Use |
|
|
862
|
+
|------|-----------|------------|
|
|
863
|
+
| Read files | cat, head, tail, less | read_file, read_file_range |
|
|
864
|
+
| Search content | grep, rg, ack | ripgrep |
|
|
865
|
+
| Find files | find, ls -R, locate | glob_search |
|
|
866
|
+
| Edit files | sed, awk, perl -i | edit_file_replace |
|
|
867
|
+
| Create/write files | echo >, cat <<EOF | write_file |
|
|
868
|
+
|
|
869
|
+
**Why this matters:**
|
|
870
|
+
- bash output truncated at 8000 chars → long content gets lost
|
|
871
|
+
- Dedicated tools have built-in limits and error handling
|
|
872
|
+
- File integrity tracking only works with dedicated tools
|
|
873
|
+
- Results display properly in UI with dedicated tools
|
|
874
|
+
|
|
875
|
+
**Correct patterns:**
|
|
876
|
+
```
|
|
877
|
+
# Find files → glob_search
|
|
878
|
+
glob_search({ pattern: "**/*.ts" })
|
|
879
|
+
|
|
880
|
+
# Search content → ripgrep
|
|
881
|
+
ripgrep({ pattern: "TODO", output_mode: "content", head_limit: 20 })
|
|
882
|
+
|
|
883
|
+
# Read file → read_file
|
|
884
|
+
read_file({ filePath: "src/index.js" })
|
|
885
|
+
|
|
886
|
+
# Large file → read_file_range
|
|
887
|
+
read_file_range({ filePath: "big.log", startLine: 1, endLine: 500 })
|
|
888
|
+
```
|
|
889
|
+
|
|
890
|
+
**Other tool usage rules:**
|
|
818
891
|
- Auto-exclusions trusted: node_modules, .git, etc. are automatically excluded
|
|
819
892
|
- Parallel when possible: Execute independent tool calls simultaneously
|
|
893
|
+
- Check output limits: ripgrep has 30KB limit, read_file has 2000 line limit
|
|
820
894
|
|
|
821
895
|
## Error handling
|
|
822
896
|
|
|
@@ -827,6 +901,44 @@ When errors occur, handle them autonomously:
|
|
|
827
901
|
- Fix immediately: Don't report errors - fix them and continue
|
|
828
902
|
- Iterate as needed: If fix doesn't work, try alternative approaches
|
|
829
903
|
|
|
904
|
+
## CRITICAL - Avoiding repetitive behavior
|
|
905
|
+
|
|
906
|
+
**You MUST recognize and break out of repetitive patterns:**
|
|
907
|
+
|
|
908
|
+
SELF-AWARENESS RULES:
|
|
909
|
+
1. **Same action, same result = STOP**: If you execute the same command and get the same result twice, DO NOT try it a third time
|
|
910
|
+
2. **Analyze before retrying**: When something fails, understand WHY before trying again
|
|
911
|
+
3. **Change approach**: If an approach isn't working, try a fundamentally different strategy
|
|
912
|
+
4. **Admit limitations**: If you cannot solve a problem after 2-3 different approaches, clearly tell the user
|
|
913
|
+
|
|
914
|
+
FORBIDDEN PATTERNS:
|
|
915
|
+
- Running the same bash command repeatedly hoping for different results
|
|
916
|
+
- Re-reading the same file without making changes
|
|
917
|
+
- Retrying the same edit that failed without fixing the root cause
|
|
918
|
+
- Looping through identical tool calls
|
|
919
|
+
|
|
920
|
+
REQUIRED BEHAVIOR:
|
|
921
|
+
- After failure: STOP → ANALYZE root cause → TRY DIFFERENT approach
|
|
922
|
+
- After 2 identical failures: STOP completely and inform user
|
|
923
|
+
- When stuck: Clearly explain what you tried, why it failed, and ask for guidance
|
|
924
|
+
|
|
925
|
+
EXAMPLE - WRONG:
|
|
926
|
+
```
|
|
927
|
+
bash("node test.js") → Error
|
|
928
|
+
bash("node test.js") → Same error
|
|
929
|
+
bash("node test.js") → Same error (FORBIDDEN - endless loop!)
|
|
930
|
+
```
|
|
931
|
+
|
|
932
|
+
EXAMPLE - CORRECT:
|
|
933
|
+
```
|
|
934
|
+
bash("node test.js") → Error: "module not found"
|
|
935
|
+
STOP and ANALYZE: The error says module is not found
|
|
936
|
+
read_file("test.js") → Check what module is being imported
|
|
937
|
+
DIFFERENT APPROACH: Fix the import or install the module
|
|
938
|
+
```
|
|
939
|
+
|
|
940
|
+
**If you find yourself doing the same thing more than twice, you have FAILED to think properly. STOP and THINK.**
|
|
941
|
+
|
|
830
942
|
# Response format
|
|
831
943
|
|
|
832
944
|
## Tool call structure
|
|
@@ -1092,3 +1204,4 @@ ASK USER:
|
|
|
1092
1204
|
|
|
1093
1205
|
DECIDE YOURSELF:
|
|
1094
1206
|
- All implementation details (HOW to implement)
|
|
1207
|
+
|