tmpa-cli 1.0.7 β 1.0.8
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 +48 -4
- package/bin/index.js +125 -21
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -25,18 +25,21 @@ Make sure you have **Node.js** (v18+) installed in your terminal. Run the follow
|
|
|
25
25
|
|
|
26
26
|
```bash
|
|
27
27
|
npm install -g tmpa-cli
|
|
28
|
+
```
|
|
28
29
|
|
|
29
30
|
2. Installation via GitHub
|
|
30
31
|
βYou can also install directly from the GitHub repository:
|
|
31
32
|
|
|
33
|
+
```bash
|
|
32
34
|
npm install -g git+[https://github.com/zayyanathariz63-pixel/TMPA-CLI.git](https://github.com/zayyanathariz63-pixel/TMPA-CLI.git)
|
|
35
|
+
```
|
|
33
36
|
|
|
34
37
|
π Usage
|
|
35
38
|
βOnce installed, simply open your terminal and type:
|
|
36
39
|
|
|
37
|
-
bash
|
|
40
|
+
```bash
|
|
38
41
|
tmpa
|
|
39
|
-
|
|
42
|
+
```
|
|
40
43
|
π First-Time Setup
|
|
41
44
|
βWhen you run the application for the first time, you will be prompted to enter:
|
|
42
45
|
|
|
@@ -49,10 +52,11 @@ tmpa
|
|
|
49
52
|
βWhile inside the TMPA > chat session, you can use the following control commands:
|
|
50
53
|
|
|
51
54
|
Command Description
|
|
52
|
-
/config
|
|
53
|
-
/clear
|
|
55
|
+
/config--> Update or change stored API Key and API Endpoint
|
|
56
|
+
/clear--> Clear the terminal screen and display the main banner
|
|
54
57
|
/exit --> Exit the TMPA CLI application
|
|
55
58
|
|
|
59
|
+
|
|
56
60
|
Preview Example :
|
|
57
61
|
βββββββββββββ βββββββββββ ββββββ
|
|
58
62
|
ββββββββββββββ βββββββββββββββββββββ
|
|
@@ -65,6 +69,46 @@ Preview Example :
|
|
|
65
69
|
/config : Change API | /clear : Clear Screen | /exit : Exit
|
|
66
70
|
βββββββββββββββββββββββββββββββββββββββββββββββββββ
|
|
67
71
|
|
|
72
|
+
|
|
73
|
+
## π¦ Prerequisites
|
|
74
|
+
|
|
75
|
+
Make sure you have **Node.js** (`v18.0.0` or higher) installed in your system:
|
|
76
|
+
|
|
77
|
+
windows :
|
|
78
|
+
```bash
|
|
79
|
+
winget install OpenJS.NodeJS
|
|
80
|
+
```
|
|
81
|
+
|
|
82
|
+
Linux :
|
|
83
|
+
```bash
|
|
84
|
+
sudo apt update
|
|
85
|
+
sudo apt install nodejs npm
|
|
86
|
+
```
|
|
87
|
+
|
|
88
|
+
3. macOS :
|
|
89
|
+
```bash
|
|
90
|
+
brew install node
|
|
91
|
+
```
|
|
92
|
+
|
|
93
|
+
π How to Check the Installation Results: Once the process is complete, close and reopen your terminal, then type the following command to verify that npm is installed:
|
|
94
|
+
|
|
95
|
+
node.js :
|
|
96
|
+
```bash
|
|
97
|
+
node -v
|
|
98
|
+
```
|
|
99
|
+
npm :
|
|
100
|
+
```bash
|
|
101
|
+
npm -v
|
|
102
|
+
```
|
|
103
|
+
|
|
104
|
+
|
|
105
|
+
If you are using Termux (Android), you can install or update Node.js v18+ using:
|
|
106
|
+
|
|
107
|
+
```Bash
|
|
108
|
+
pkg update && pkg install nodejs-lts -y
|
|
109
|
+
```
|
|
110
|
+
|
|
111
|
+
|
|
68
112
|
TMPA > hello, who are you?
|
|
69
113
|
TMPA CLI processing...
|
|
70
114
|
TMPA CLI : I am an AI assistant ready to help you!
|
package/bin/index.js
CHANGED
|
@@ -22,6 +22,16 @@ const C = {
|
|
|
22
22
|
darkGray: '\x1b[38;2;71;85;105m'
|
|
23
23
|
};
|
|
24
24
|
|
|
25
|
+
const PROVIDERS = {
|
|
26
|
+
'1': { name: 'OpenRouter', endpoint: 'https://openrouter.ai/api/v1', defaultModel: 'google/gemini-2.5-flash' },
|
|
27
|
+
'2': { name: 'Groq', endpoint: 'https://api.groq.com/openai/v1', defaultModel: 'llama-3.3-70b-versatile' },
|
|
28
|
+
'3': { name: 'NVIDIA NIM', endpoint: 'https://integrate.api.nvidia.com/v1', defaultModel: 'meta/llama-3.1-70b-instruct' },
|
|
29
|
+
'4': { name: 'OpenAI', endpoint: 'https://api.openai.com/v1', defaultModel: 'gpt-4o-mini' },
|
|
30
|
+
'5': { name: 'Anthropic', endpoint: 'https://api.anthropic.com/v1', defaultModel: 'claude-3-5-haiku-20241022' },
|
|
31
|
+
'6': { name: 'Google Gemini', endpoint: 'https://generativelanguage.googleapis.com/v1beta/models/gemini-2.5-flash:generateContent', defaultModel: 'gemini-2.5-flash' },
|
|
32
|
+
'7': { name: 'Custom / Auto-Detect', endpoint: '', defaultModel: '' }
|
|
33
|
+
};
|
|
34
|
+
|
|
25
35
|
function loadConfig() {
|
|
26
36
|
if (fs.existsSync(CONFIG_FILE)) {
|
|
27
37
|
try {
|
|
@@ -48,7 +58,7 @@ ${C.c4} βββ βββ βββ ββββββ βββ β
|
|
|
48
58
|
${C.c4} βββ βββ ββββββ βββ βββ${C.reset}
|
|
49
59
|
${C.darkGray}ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ${C.reset}
|
|
50
60
|
${C.reset}The Multi Platform AI ${C.green}[Interactive Mode]${C.reset}
|
|
51
|
-
${C.gray}/config : Set API | /
|
|
61
|
+
${C.gray}/config : Set API | /models : View Models | /uninstall : Remove | /exit : Exit${C.reset}
|
|
52
62
|
${C.darkGray}ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ${C.reset}
|
|
53
63
|
`);
|
|
54
64
|
}
|
|
@@ -61,45 +71,140 @@ const rl = readline.createInterface({
|
|
|
61
71
|
let config = loadConfig();
|
|
62
72
|
|
|
63
73
|
function askConfig(callback) {
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
74
|
+
console.log(`\n${C.cyan}[+] Choose AI Provider:${C.reset}`);
|
|
75
|
+
console.log(` ${C.yellow}1.${C.reset} OpenRouter`);
|
|
76
|
+
console.log(` ${C.yellow}2.${C.reset} Groq`);
|
|
77
|
+
console.log(` ${C.yellow}3.${C.reset} NVIDIA NIM`);
|
|
78
|
+
console.log(` ${C.yellow}4.${C.reset} OpenAI`);
|
|
79
|
+
console.log(` ${C.yellow}5.${C.reset} Anthropic`);
|
|
80
|
+
console.log(` ${C.yellow}6.${C.reset} Google Gemini (Default)`);
|
|
81
|
+
console.log(` ${C.yellow}7.${C.reset} Custom / Auto-Detect Endpoint\n`);
|
|
82
|
+
|
|
83
|
+
rl.question(`${C.yellow}[>] Select Provider (1-7):${C.reset} `, (choice) => {
|
|
84
|
+
const selected = PROVIDERS[choice.trim()] || PROVIDERS['6'];
|
|
85
|
+
|
|
86
|
+
rl.question(`${C.yellow}[>] Enter API Key for ${selected.name}:${C.reset} `, (apiKey) => {
|
|
87
|
+
if (choice.trim() === '7') {
|
|
88
|
+
rl.question(`${C.yellow}[>] Enter Custom Base URL / Endpoint:${C.reset} `, (customUrl) => {
|
|
89
|
+
rl.question(`${C.yellow}[>] Enter Model Name:${C.reset} `, (customModel) => {
|
|
90
|
+
config.provider = 'Custom';
|
|
91
|
+
config.apiKey = apiKey.trim();
|
|
92
|
+
config.endpoint = customUrl.trim();
|
|
93
|
+
config.model = customModel.trim();
|
|
94
|
+
saveConfig(config);
|
|
95
|
+
console.log(`${C.green}[+] Configuration saved successfully!${C.reset}\n`);
|
|
96
|
+
if (callback) callback();
|
|
97
|
+
});
|
|
98
|
+
});
|
|
99
|
+
} else {
|
|
100
|
+
config.provider = selected.name;
|
|
101
|
+
config.apiKey = apiKey.trim();
|
|
102
|
+
config.endpoint = selected.endpoint;
|
|
103
|
+
config.model = selected.defaultModel;
|
|
104
|
+
saveConfig(config);
|
|
105
|
+
console.log(`${C.green}[+] Connected to ${selected.name} (${selected.defaultModel})${C.reset}\n`);
|
|
106
|
+
if (callback) callback();
|
|
107
|
+
}
|
|
71
108
|
});
|
|
72
109
|
});
|
|
73
110
|
}
|
|
74
111
|
|
|
112
|
+
async function fetchAvailableModels() {
|
|
113
|
+
if (!config.apiKey) {
|
|
114
|
+
console.log(`${C.red}[x] API Key is not set. Use /config first.${C.reset}\n`);
|
|
115
|
+
return startPrompt();
|
|
116
|
+
}
|
|
117
|
+
|
|
118
|
+
console.log(`${C.yellow}[...] Fetching models for ${config.provider || 'Provider'}...${C.reset}`);
|
|
119
|
+
|
|
120
|
+
try {
|
|
121
|
+
let url = config.endpoint;
|
|
122
|
+
if (url.endsWith('/generateContent')) {
|
|
123
|
+
console.log(`${C.yellow}[!] Google Gemini default endpoint uses fixed model: ${config.model}${C.reset}\n`);
|
|
124
|
+
return startPrompt();
|
|
125
|
+
}
|
|
126
|
+
|
|
127
|
+
// Auto-detect /models endpoint
|
|
128
|
+
let modelsUrl = url.endsWith('/models') ? url : `${url.replace(/\/chat\/completions$/, '')}/models`;
|
|
129
|
+
|
|
130
|
+
const response = await fetch(modelsUrl, {
|
|
131
|
+
method: 'GET',
|
|
132
|
+
headers: {
|
|
133
|
+
'Authorization': `Bearer ${config.apiKey}`,
|
|
134
|
+
'Content-Type': 'application/json'
|
|
135
|
+
}
|
|
136
|
+
});
|
|
137
|
+
|
|
138
|
+
const data = await response.json();
|
|
139
|
+
|
|
140
|
+
if (data.data && Array.isArray(data.data)) {
|
|
141
|
+
console.log(`\n${C.cyan}=== Available Models ===${C.reset}`);
|
|
142
|
+
const modelList = data.data.slice(0, 20); // Limit top 20 models
|
|
143
|
+
modelList.forEach((m, idx) => {
|
|
144
|
+
console.log(` ${C.yellow}${idx + 1}.${C.reset} ${m.id}`);
|
|
145
|
+
});
|
|
146
|
+
console.log(`${C.darkGray}------------------------------------------------------------${C.reset}`);
|
|
147
|
+
|
|
148
|
+
rl.question(`\n${C.yellow}[>] Enter Model Name to use (or press Enter to keep current: ${config.model}):${C.reset} `, (newModel) => {
|
|
149
|
+
if (newModel.trim()) {
|
|
150
|
+
config.model = newModel.trim();
|
|
151
|
+
saveConfig(config);
|
|
152
|
+
console.log(`${C.green}[+] Active model updated to: ${config.model}${C.reset}\n`);
|
|
153
|
+
} else {
|
|
154
|
+
console.log(`${C.gray}Keeping current model: ${config.model}${C.reset}\n`);
|
|
155
|
+
}
|
|
156
|
+
startPrompt();
|
|
157
|
+
});
|
|
158
|
+
} else {
|
|
159
|
+
console.log(`${C.red}[x] Unable to fetch models automatically from this provider.${C.reset}\n`);
|
|
160
|
+
startPrompt();
|
|
161
|
+
}
|
|
162
|
+
} catch (err) {
|
|
163
|
+
console.log(`${C.red}[x] Error fetching models: ${err.message}${C.reset}\n`);
|
|
164
|
+
startPrompt();
|
|
165
|
+
}
|
|
166
|
+
}
|
|
167
|
+
|
|
75
168
|
async function handleChat(prompt) {
|
|
76
169
|
if (!config.apiKey) {
|
|
77
170
|
console.log(`${C.yellow}[!] API Key is not set.${C.reset}`);
|
|
78
171
|
return askConfig(() => startPrompt());
|
|
79
172
|
}
|
|
80
173
|
|
|
81
|
-
const defaultEndpoint = 'https://generativelanguage.googleapis.com/v1beta/models/gemini-2.5-flash:generateContent';
|
|
82
|
-
const targetEndpoint = config.endpoint || defaultEndpoint;
|
|
83
|
-
|
|
84
174
|
console.log(`${C.yellow}TMPA CLI processing...${C.reset}`);
|
|
85
175
|
|
|
86
176
|
try {
|
|
87
|
-
|
|
88
|
-
|
|
177
|
+
let url = config.endpoint;
|
|
178
|
+
let headers = { 'Content-Type': 'application/json' };
|
|
179
|
+
let bodyData = {};
|
|
89
180
|
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
181
|
+
// Auto-Detect Request Format (Google Gemini vs OpenAI Compatible)
|
|
182
|
+
if (url.includes('googleapis.com')) {
|
|
183
|
+
url = `${url}?key=${config.apiKey}`;
|
|
184
|
+
bodyData = { contents: [{ parts: [{ text: prompt }] }] };
|
|
185
|
+
} else {
|
|
186
|
+
// OpenAI Compatible (OpenRouter, Groq, NVIDIA, OpenAI, dll)
|
|
187
|
+
if (!url.endsWith('/chat/completions')) {
|
|
188
|
+
url = `${url.replace(/\/$/, '')}/chat/completions`;
|
|
189
|
+
}
|
|
190
|
+
headers['Authorization'] = `Bearer ${config.apiKey}`;
|
|
191
|
+
bodyData = {
|
|
192
|
+
model: config.model || 'gpt-3.5-turbo',
|
|
193
|
+
messages: [{ role: 'user', content: prompt }]
|
|
194
|
+
};
|
|
195
|
+
}
|
|
93
196
|
|
|
94
197
|
const response = await fetch(url, {
|
|
95
198
|
method: 'POST',
|
|
96
|
-
headers:
|
|
199
|
+
headers: headers,
|
|
97
200
|
body: JSON.stringify(bodyData)
|
|
98
201
|
});
|
|
99
202
|
|
|
100
203
|
const data = await response.json();
|
|
101
204
|
|
|
102
|
-
if (data.
|
|
205
|
+
if (data.choices && data.choices[0]?.message?.content) {
|
|
206
|
+
console.log(`\n${C.c1}TMPA CLI (${config.model || 'AI'}) :${C.reset} ${data.choices[0].message.content}\n`);
|
|
207
|
+
} else if (data.candidates && data.candidates[0]?.content?.parts[0]?.text) {
|
|
103
208
|
console.log(`\n${C.c1}TMPA CLI :${C.reset} ${data.candidates[0].content.parts[0].text}\n`);
|
|
104
209
|
} else if (data.error) {
|
|
105
210
|
console.log(`\n${C.red}[x] API Error: ${data.error.message || JSON.stringify(data.error)}${C.reset}\n`);
|
|
@@ -148,9 +253,8 @@ function startPrompt() {
|
|
|
148
253
|
startPrompt();
|
|
149
254
|
} else if (cmd === '/config') {
|
|
150
255
|
askConfig(() => startPrompt());
|
|
151
|
-
} else if (cmd === '/
|
|
152
|
-
|
|
153
|
-
startPrompt();
|
|
256
|
+
} else if (cmd === '/models') {
|
|
257
|
+
fetchAvailableModels();
|
|
154
258
|
} else if (cmd === '/uninstall') {
|
|
155
259
|
handleUninstall();
|
|
156
260
|
} else if (cmd === '') {
|