aiexecode 1.0.94 → 1.0.96
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 +210 -87
- package/index.js +33 -1
- package/package.json +3 -3
- 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/src/LLMClient/client.js +392 -16
- package/src/LLMClient/converters/responses-to-claude.js +67 -18
- package/src/LLMClient/converters/responses-to-zai.js +608 -0
- package/src/LLMClient/errors.js +18 -4
- package/src/LLMClient/index.js +5 -0
- package/src/ai_based/completion_judge.js +35 -4
- package/src/ai_based/orchestrator.js +146 -35
- package/src/commands/agents.js +70 -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 +43 -7
- package/src/commands/skills.js +46 -0
- package/src/config/ai_models.js +96 -5
- package/src/config/constants.js +71 -0
- package/src/frontend/components/HelpView.js +106 -2
- package/src/frontend/components/SetupWizard.js +53 -8
- package/src/frontend/utils/toolUIFormatter.js +261 -0
- package/src/system/agents_loader.js +289 -0
- package/src/system/ai_request.js +147 -9
- package/src/system/command_parser.js +33 -3
- package/src/system/conversation_state.js +265 -0
- package/src/system/custom_command_loader.js +386 -0
- package/src/system/session.js +59 -35
- package/src/system/skill_loader.js +318 -0
- package/src/system/tool_approval.js +10 -0
- package/src/tools/file_reader.js +49 -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 +38 -2
- package/src/util/config_migration.js +174 -0
- package/src/util/path_validator.js +178 -0
- package/src/util/prompt_loader.js +68 -1
- package/src/util/safe_fs.js +43 -3
- package/payload_viewer/out/_next/static/chunks/ecd2072ebf41611f.css +0 -3
- /package/payload_viewer/out/_next/static/{wkEKh6i9XPSyP6rjDRvHn → lHmNygVpv4N1VR0LdnwkJ}/_buildManifest.js +0 -0
- /package/payload_viewer/out/_next/static/{wkEKh6i9XPSyP6rjDRvHn → lHmNygVpv4N1VR0LdnwkJ}/_clientMiddlewareManifest.json +0 -0
- /package/payload_viewer/out/_next/static/{wkEKh6i9XPSyP6rjDRvHn → lHmNygVpv4N1VR0LdnwkJ}/_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) => {
|