expxagents 0.29.1 → 0.29.3
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.
|
@@ -1,36 +1,62 @@
|
|
|
1
1
|
import readline from 'node:readline';
|
|
2
|
+
import path from 'node:path';
|
|
2
3
|
import dotenv from 'dotenv';
|
|
3
4
|
import { AgentRunner, SessionManager, SUPPORTED_MODELS, DEFAULT_MODEL } from '@expxagents/agent';
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
const COLORS = {
|
|
5
|
+
import { getVersion } from '../utils/version.js';
|
|
6
|
+
const C = {
|
|
7
7
|
reset: '\x1b[0m',
|
|
8
8
|
dim: '\x1b[2m',
|
|
9
9
|
green: '\x1b[32m',
|
|
10
10
|
cyan: '\x1b[36m',
|
|
11
11
|
yellow: '\x1b[33m',
|
|
12
12
|
magenta: '\x1b[35m',
|
|
13
|
+
blue: '\x1b[34m',
|
|
14
|
+
white: '\x1b[37m',
|
|
13
15
|
bold: '\x1b[1m',
|
|
16
|
+
bgCyan: '\x1b[46m',
|
|
17
|
+
bgBlue: '\x1b[44m',
|
|
14
18
|
};
|
|
15
|
-
function printBanner(model) {
|
|
19
|
+
function printBanner(model, version) {
|
|
16
20
|
const modelInfo = SUPPORTED_MODELS.find(m => m.id === model);
|
|
17
21
|
const label = modelInfo?.name ?? model;
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
console.log(
|
|
21
|
-
console.log(`${
|
|
22
|
+
const cwd = process.cwd();
|
|
23
|
+
const dir = cwd.split('/').slice(-2).join('/');
|
|
24
|
+
console.log('');
|
|
25
|
+
console.log(`${C.cyan} ╔══════════════════════════════════════════════════╗${C.reset}`);
|
|
26
|
+
console.log(`${C.cyan} ║${C.reset} ${C.cyan}║${C.reset}`);
|
|
27
|
+
console.log(`${C.cyan} ║${C.reset} ${C.bold}${C.cyan}▓▓▓ ExpxAgents CLI ▓▓▓${C.reset} ${C.cyan}║${C.reset}`);
|
|
28
|
+
console.log(`${C.cyan} ║${C.reset} ${C.dim}AI Coding Agent — powered by OpenRouter${C.reset} ${C.cyan}║${C.reset}`);
|
|
29
|
+
console.log(`${C.cyan} ║${C.reset} ${C.cyan}║${C.reset}`);
|
|
30
|
+
console.log(`${C.cyan} ╚══════════════════════════════════════════════════╝${C.reset}`);
|
|
31
|
+
console.log('');
|
|
32
|
+
console.log(` ${C.dim}Model${C.reset} ${C.yellow}${label}${C.reset}`);
|
|
33
|
+
console.log(` ${C.dim}Dir${C.reset} ${C.white}${dir}${C.reset}`);
|
|
34
|
+
console.log(` ${C.dim}Version${C.reset} ${C.dim}v${version}${C.reset}`);
|
|
35
|
+
console.log(` ${C.dim}Tools${C.reset} ${C.green}14 tools${C.reset} ${C.dim}(files, bash, web, search)${C.reset}`);
|
|
36
|
+
console.log('');
|
|
37
|
+
console.log(` ${C.dim}Tips: ${C.bold}/help${C.reset}${C.dim} commands • ${C.bold}/models${C.reset}${C.dim} list models • ${C.bold}/quit${C.reset}${C.dim} exit${C.reset}`);
|
|
38
|
+
console.log(` ${C.dim}──────────────────────────────────────────────────${C.reset}`);
|
|
39
|
+
console.log('');
|
|
22
40
|
}
|
|
23
41
|
function printHelp() {
|
|
24
|
-
console.log(
|
|
25
|
-
${
|
|
26
|
-
${
|
|
27
|
-
${
|
|
28
|
-
${
|
|
29
|
-
${
|
|
30
|
-
${
|
|
31
|
-
`);
|
|
42
|
+
console.log('');
|
|
43
|
+
console.log(` ${C.bold}${C.cyan}Commands${C.reset}`);
|
|
44
|
+
console.log(` ${C.dim}──────────────────────────────────────${C.reset}`);
|
|
45
|
+
console.log(` ${C.cyan}/help${C.reset} Show this help`);
|
|
46
|
+
console.log(` ${C.cyan}/model ${C.dim}<id>${C.reset} Switch model`);
|
|
47
|
+
console.log(` ${C.cyan}/models${C.reset} List available models`);
|
|
48
|
+
console.log(` ${C.cyan}/clear${C.reset} Clear conversation`);
|
|
49
|
+
console.log(` ${C.cyan}/quit${C.reset} Exit`);
|
|
50
|
+
console.log('');
|
|
51
|
+
console.log(` ${C.bold}${C.cyan}Shortcuts${C.reset}`);
|
|
52
|
+
console.log(` ${C.dim}──────────────────────────────────────${C.reset}`);
|
|
53
|
+
console.log(` ${C.cyan}Ctrl+C${C.reset} Exit`);
|
|
54
|
+
console.log(` ${C.cyan}Ctrl+D${C.reset} Exit`);
|
|
55
|
+
console.log('');
|
|
32
56
|
}
|
|
33
57
|
export async function cliChatCommand(options) {
|
|
58
|
+
// Load .env from the user's current working directory (explicit path for npx compatibility)
|
|
59
|
+
dotenv.config({ path: path.resolve(process.cwd(), '.env') });
|
|
34
60
|
const apiKey = process.env.OPENROUTER_API_KEY;
|
|
35
61
|
if (!apiKey) {
|
|
36
62
|
console.error('OPENROUTER_API_KEY is not set. Get one at https://openrouter.ai/keys');
|
|
@@ -54,7 +80,7 @@ export async function cliChatCommand(options) {
|
|
|
54
80
|
const summary = typeof args === 'object' && args !== null
|
|
55
81
|
? Object.entries(args).map(([k, v]) => `${k}=${String(v).slice(0, 60)}`).join(', ')
|
|
56
82
|
: String(args).slice(0, 80);
|
|
57
|
-
process.stderr.write(
|
|
83
|
+
process.stderr.write(` ${C.dim}${C.cyan}⚡${C.reset} ${C.dim}${tool}${C.reset} ${C.dim}${summary}${C.reset}\n`);
|
|
58
84
|
},
|
|
59
85
|
});
|
|
60
86
|
try {
|
|
@@ -68,11 +94,11 @@ export async function cliChatCommand(options) {
|
|
|
68
94
|
return;
|
|
69
95
|
}
|
|
70
96
|
// Interactive REPL mode
|
|
71
|
-
printBanner(model);
|
|
97
|
+
printBanner(model, getVersion());
|
|
72
98
|
const rl = readline.createInterface({
|
|
73
99
|
input: process.stdin,
|
|
74
100
|
output: process.stdout,
|
|
75
|
-
prompt: `${
|
|
101
|
+
prompt: `${C.bold}${C.cyan}❯${C.reset} `,
|
|
76
102
|
});
|
|
77
103
|
rl.prompt();
|
|
78
104
|
rl.on('line', async (line) => {
|
|
@@ -88,7 +114,7 @@ export async function cliChatCommand(options) {
|
|
|
88
114
|
case '/quit':
|
|
89
115
|
case '/exit':
|
|
90
116
|
case '/q':
|
|
91
|
-
console.log(
|
|
117
|
+
console.log(`\n ${C.dim}Goodbye! ${C.cyan}✦${C.reset}\n`);
|
|
92
118
|
process.exit(0);
|
|
93
119
|
break;
|
|
94
120
|
case '/help':
|
|
@@ -96,37 +122,37 @@ export async function cliChatCommand(options) {
|
|
|
96
122
|
rl.prompt();
|
|
97
123
|
return;
|
|
98
124
|
case '/models':
|
|
99
|
-
console.log(`\n${
|
|
125
|
+
console.log(`\n${C.bold}Available models:${C.reset}`);
|
|
100
126
|
for (const m of SUPPORTED_MODELS) {
|
|
101
|
-
const active = m.id === model ? ` ${
|
|
102
|
-
console.log(` ${
|
|
127
|
+
const active = m.id === model ? ` ${C.green}(active)${C.reset}` : '';
|
|
128
|
+
console.log(` ${C.cyan}${m.id}${C.reset} — ${m.name} (${(m.contextWindow / 1000).toFixed(0)}K ctx)${active}`);
|
|
103
129
|
}
|
|
104
130
|
console.log('');
|
|
105
131
|
rl.prompt();
|
|
106
132
|
return;
|
|
107
133
|
case '/model':
|
|
108
134
|
if (!args[0]) {
|
|
109
|
-
console.log(`Current model: ${
|
|
135
|
+
console.log(`Current model: ${C.yellow}${model}${C.reset}`);
|
|
110
136
|
}
|
|
111
137
|
else {
|
|
112
138
|
model = args[0];
|
|
113
139
|
const info = SUPPORTED_MODELS.find(m => m.id === model);
|
|
114
140
|
if (info) {
|
|
115
|
-
console.log(`${
|
|
141
|
+
console.log(`${C.green}Switched to ${info.name}${C.reset}`);
|
|
116
142
|
}
|
|
117
143
|
else {
|
|
118
|
-
console.log(`${
|
|
144
|
+
console.log(`${C.yellow}Warning: "${model}" is not in curated list. Tool use may not work.${C.reset}`);
|
|
119
145
|
}
|
|
120
146
|
}
|
|
121
147
|
rl.prompt();
|
|
122
148
|
return;
|
|
123
149
|
case '/clear':
|
|
124
150
|
sessionManager.create(sessionId, process.cwd());
|
|
125
|
-
console.log(`${
|
|
151
|
+
console.log(`${C.dim}Conversation cleared.${C.reset}`);
|
|
126
152
|
rl.prompt();
|
|
127
153
|
return;
|
|
128
154
|
default:
|
|
129
|
-
console.log(`${
|
|
155
|
+
console.log(`${C.dim}Unknown command: ${cmd}. Type /help for commands.${C.reset}`);
|
|
130
156
|
rl.prompt();
|
|
131
157
|
return;
|
|
132
158
|
}
|
|
@@ -145,11 +171,11 @@ export async function cliChatCommand(options) {
|
|
|
145
171
|
const summary = typeof args === 'object' && args !== null
|
|
146
172
|
? Object.entries(args).map(([k, v]) => `${k}=${String(v).slice(0, 60)}`).join(', ')
|
|
147
173
|
: String(args).slice(0, 80);
|
|
148
|
-
process.stderr.write(
|
|
174
|
+
process.stderr.write(` ${C.dim}${C.cyan}⚡${C.reset} ${C.dim}${tool}${C.reset} ${C.dim}${summary}${C.reset}\n`);
|
|
149
175
|
},
|
|
150
176
|
onAskUser: async (question) => {
|
|
151
177
|
return new Promise((resolve) => {
|
|
152
|
-
rl.question(
|
|
178
|
+
rl.question(`\n ${C.magenta}? ${question}${C.reset}\n ${C.bold}${C.cyan}❯${C.reset} `, resolve);
|
|
153
179
|
});
|
|
154
180
|
},
|
|
155
181
|
});
|
|
@@ -158,12 +184,12 @@ export async function cliChatCommand(options) {
|
|
|
158
184
|
console.log('\n');
|
|
159
185
|
}
|
|
160
186
|
catch (err) {
|
|
161
|
-
console.error(`\n${
|
|
187
|
+
console.error(`\n${C.yellow}Error: ${err instanceof Error ? err.message : String(err)}${C.reset}\n`);
|
|
162
188
|
}
|
|
163
189
|
rl.prompt();
|
|
164
190
|
});
|
|
165
191
|
rl.on('close', () => {
|
|
166
|
-
console.log(`\n${
|
|
192
|
+
console.log(`\n${C.dim}Goodbye!${C.reset}`);
|
|
167
193
|
process.exit(0);
|
|
168
194
|
});
|
|
169
195
|
}
|