@yamzzdev/aiyamz 1.0.1 → 1.0.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.
package/bin/aiyamz.js CHANGED
@@ -10,31 +10,39 @@ require('dotenv').config();
10
10
 
11
11
  const program = new Command();
12
12
 
13
- // Show banner
14
13
  console.log(chalk.cyan(figlet.textSync('AIYamz', { font: 'Small' })));
15
- console.log(chalk.gray('by yamzzdev - AI Chat Package (FREE)\n'));
14
+ console.log(chalk.gray('by yamzzdev - AI Chat Package\n'));
16
15
 
17
16
  program
18
- .version('1.0.0')
19
- .description('AI Chat CLI by yamzzdev - Powered by Google Gemini (FREE)');
17
+ .version('1.0.2')
18
+ .description('AI Chat CLI by yamzzdev - Powered by Groq (FREE)');
20
19
 
21
20
  program
22
21
  .command('chat')
23
22
  .description('Start interactive chat with AI')
24
- .option('-k, --key <key>', 'Gemini API key')
23
+ .option('-k, --key <key>', 'Groq API key')
24
+ .option('-m, --model <model>', 'Model to use (llama3-8b-8192, llama3-70b-8192, mixtral-8x7b-32768, gemma2-9b-it)')
25
25
  .action(async (options) => {
26
- const apiKey = options.key || process.env.GEMINI_API_KEY;
26
+ const apiKey = options.key || process.env.GROQ_API_KEY;
27
27
 
28
28
  if (!apiKey) {
29
- console.log(chalk.red(' No API key found!'));
30
- console.log(chalk.yellow('Get your free API key: https://aistudio.google.com/apikey'));
31
- console.log(chalk.gray('Then run: export GEMINI_API_KEY=your_key_here\n'));
29
+ console.log(chalk.red('Error: No API key found'));
30
+ console.log(chalk.yellow('Get your free API key: https://console.groq.com/keys'));
31
+ console.log(chalk.gray('Then run: export GROQ_API_KEY=your_key_here\n'));
32
+ console.log(chalk.gray('Or use: aiyamz chat --key your_key_here\n'));
32
33
  return;
33
34
  }
34
35
 
35
36
  const ai = new AIYamz(apiKey);
36
37
 
37
- console.log(chalk.green('✅ AI Ready! Type your message (type "exit" to quit)\n'));
38
+ if (options.model) {
39
+ ai.provider.setModel(options.model);
40
+ console.log(chalk.gray(`Using model: ${options.model}\n`));
41
+ } else {
42
+ console.log(chalk.gray(`Using model: ${ai.provider.model}\n`));
43
+ }
44
+
45
+ console.log(chalk.green('AI Ready! Type your message (type "exit" to quit, "clear" to clear history)\n'));
38
46
 
39
47
  while (true) {
40
48
  const { message } = await inquirer.prompt([
@@ -47,13 +55,28 @@ program
47
55
  ]);
48
56
 
49
57
  if (message.toLowerCase() === 'exit') {
50
- console.log(chalk.yellow('\n👋 Bye!'));
58
+ console.log(chalk.yellow('\nGoodbye!\n'));
51
59
  break;
52
60
  }
53
61
 
54
62
  if (message.toLowerCase() === 'clear') {
55
63
  ai.clearHistory();
56
- console.log(chalk.green('History cleared!\n'));
64
+ console.log(chalk.green('History cleared\n'));
65
+ continue;
66
+ }
67
+
68
+ if (message.toLowerCase() === 'history') {
69
+ const history = ai.getHistory();
70
+ if (history.length === 0) {
71
+ console.log(chalk.gray('No history yet\n'));
72
+ } else {
73
+ console.log(chalk.yellow('\n--- Chat History ---'));
74
+ for (const entry of history.slice(-10)) {
75
+ const role = entry.role === 'user' ? chalk.cyan('You:') : chalk.magenta('AI:');
76
+ console.log(`${role} ${entry.content.substring(0, 100)}...`);
77
+ }
78
+ console.log(chalk.yellow('--------------------\n'));
79
+ }
57
80
  continue;
58
81
  }
59
82
 
@@ -61,28 +84,36 @@ program
61
84
  const response = await ai.chat(message);
62
85
  spinner.stop();
63
86
 
64
- console.log(chalk.magenta('\n🤖 AI:'), response, '\n');
87
+ console.log(chalk.magenta('\nAI:'), response, '\n');
65
88
  }
66
89
  });
67
90
 
68
91
  program
69
92
  .command('ask <question>')
70
93
  .description('Ask a single question')
71
- .option('-k, --key <key>', 'Gemini API key')
94
+ .option('-k, --key <key>', 'Groq API key')
95
+ .option('-m, --model <model>', 'Model to use')
72
96
  .action(async (question, options) => {
73
- const apiKey = options.key || process.env.GEMINI_API_KEY;
97
+ const apiKey = options.key || process.env.GROQ_API_KEY;
74
98
 
75
99
  if (!apiKey) {
76
- console.log(chalk.red(' No API key found!'));
100
+ console.log(chalk.red('Error: No API key found'));
101
+ console.log(chalk.yellow('Get your free API key: https://console.groq.com/keys'));
77
102
  return;
78
103
  }
79
104
 
80
105
  const ai = new AIYamz(apiKey);
106
+
107
+ if (options.model) {
108
+ ai.provider.setModel(options.model);
109
+ }
110
+
81
111
  const spinner = ora(chalk.gray('Thinking...')).start();
82
112
  const response = await ai.chat(question);
83
113
  spinner.stop();
84
114
 
85
- console.log(chalk.magenta('\n🤖 Answer:'), response);
115
+ console.log(chalk.magenta('\nAnswer:'), response);
116
+ console.log();
86
117
  });
87
118
 
88
119
  program
@@ -93,17 +124,58 @@ program
93
124
  {
94
125
  type: 'input',
95
126
  name: 'apiKey',
96
- message: 'Enter your Gemini API key:',
127
+ message: 'Enter your Groq API key:',
97
128
  validate: (input) => input.length > 0 || 'API key is required'
98
129
  }
99
130
  ]);
100
131
 
101
132
  const envPath = process.env.HOME + '/.aiyamz.env';
102
- const envContent = `GEMINI_API_KEY=${apiKey}`;
133
+ const envContent = `GROQ_API_KEY=${apiKey}`;
103
134
 
104
135
  require('fs').writeFileSync(envPath, envContent);
105
- console.log(chalk.green(`✅ API key saved to ${envPath}`));
106
- console.log(chalk.gray('Add this to your shell config: export GEMINI_API_KEY=your_key'));
136
+ console.log(chalk.green(`API key saved to ${envPath}`));
137
+ console.log(chalk.gray('Add this to your shell config: export GROQ_API_KEY=your_key'));
138
+ });
139
+
140
+ program
141
+ .command('models')
142
+ .description('List available models')
143
+ .action(() => {
144
+ console.log(chalk.yellow('\nAvailable Models:'));
145
+ console.log(chalk.cyan(' - llama3-8b-8192 (fast, good for general chat)'));
146
+ console.log(chalk.cyan(' - llama3-70b-8192 (smarter, more accurate)'));
147
+ console.log(chalk.cyan(' - mixtral-8x7b-32768 (large context window)'));
148
+ console.log(chalk.cyan(' - gemma2-9b-it (lightweight, fast)\n'));
149
+ });
150
+
151
+ program
152
+ .command('history')
153
+ .description('Show chat history')
154
+ .option('-k, --key <key>', 'Groq API key')
155
+ .action(async (options) => {
156
+ const apiKey = options.key || process.env.GROQ_API_KEY;
157
+
158
+ if (!apiKey) {
159
+ console.log(chalk.red('Error: No API key found'));
160
+ return;
161
+ }
162
+
163
+ const ai = new AIYamz(apiKey);
164
+ const history = ai.getHistory();
165
+
166
+ if (history.length === 0) {
167
+ console.log(chalk.gray('No chat history found\n'));
168
+ return;
169
+ }
170
+
171
+ console.log(chalk.yellow('\n=== Chat History ===\n'));
172
+ for (const entry of history) {
173
+ const role = entry.role === 'user' ? chalk.cyan('You:') : chalk.magenta('AI:');
174
+ const time = chalk.gray(`[${new Date(entry.timestamp).toLocaleString()}]`);
175
+ console.log(`${time}`);
176
+ console.log(`${role} ${entry.content}`);
177
+ console.log(chalk.gray('---\n'));
178
+ }
107
179
  });
108
180
 
109
181
  program.parse(process.argv);
package/lib/index.js CHANGED
@@ -1,29 +1,34 @@
1
- const GeminiProvider = require('./providers/gemini');
1
+ const GroqProvider = require('./providers/groq');
2
2
  const chalk = require('chalk');
3
3
  const fs = require('fs');
4
4
  const path = require('path');
5
5
 
6
6
  class AIYamz {
7
7
  constructor(apiKey) {
8
- this.apiKey = apiKey || process.env.GEMINI_API_KEY;
8
+ this.apiKey = apiKey || process.env.GROQ_API_KEY;
9
9
  if (!this.apiKey) {
10
- console.log(chalk.yellow('⚠️ No API key found!'));
11
- console.log(chalk.cyan('Get your free API key at: https://aistudio.google.com/apikey'));
12
- console.log(chalk.gray('Then set it: export GEMINI_API_KEY=your_key_here\n'));
10
+ console.log(chalk.yellow('Warning: No API key found'));
11
+ console.log(chalk.cyan('Get your free API key at: https://console.groq.com/keys'));
12
+ console.log(chalk.gray('Then set it: export GROQ_API_KEY=your_key_here\n'));
13
13
  }
14
- this.provider = new GeminiProvider(this.apiKey);
14
+ this.provider = new GroqProvider(this.apiKey);
15
15
  this.history = [];
16
+ this.configPath = path.join(process.env.HOME || process.env.USERPROFILE, '.aiyamz.json');
17
+ this.loadHistory();
16
18
  }
17
19
 
18
20
  async chat(message, options = {}) {
19
21
  if (!this.apiKey) {
20
- return ' No API key configured. Please set GEMINI_API_KEY environment variable.';
22
+ return 'Error: No API key configured. Please set GROQ_API_KEY environment variable.';
23
+ }
24
+
25
+ if (!message || message.trim() === '') {
26
+ return 'Error: Message cannot be empty.';
21
27
  }
22
28
 
23
29
  try {
24
30
  const response = await this.provider.chat(message, options);
25
31
 
26
- // Save to history
27
32
  this.history.push({
28
33
  role: 'user',
29
34
  content: message,
@@ -35,39 +40,113 @@ class AIYamz {
35
40
  timestamp: new Date().toISOString()
36
41
  });
37
42
 
43
+ this.saveHistory();
38
44
  return response;
45
+
39
46
  } catch (error) {
40
- return `❌ Error: ${error.message}`;
47
+ return `Error: ${error.message}`;
41
48
  }
42
49
  }
43
50
 
44
- async stream(message, callback) {
51
+ async stream(message, callback, options = {}) {
45
52
  if (!this.apiKey) {
46
- callback(' No API key configured.');
53
+ callback('Error: No API key configured.');
54
+ return;
55
+ }
56
+
57
+ if (!message || message.trim() === '') {
58
+ callback('Error: Message cannot be empty.');
47
59
  return;
48
60
  }
49
61
 
62
+ let fullResponse = '';
63
+
50
64
  try {
51
65
  await this.provider.streamChat(message, (chunk) => {
66
+ fullResponse += chunk;
52
67
  if (callback) callback(chunk);
68
+ }, options);
69
+
70
+ this.history.push({
71
+ role: 'user',
72
+ content: message,
73
+ timestamp: new Date().toISOString()
53
74
  });
75
+ this.history.push({
76
+ role: 'ai',
77
+ content: fullResponse,
78
+ timestamp: new Date().toISOString()
79
+ });
80
+
81
+ this.saveHistory();
82
+
54
83
  } catch (error) {
55
- callback(`❌ Error: ${error.message}`);
84
+ callback(`Error: ${error.message}`);
56
85
  }
57
86
  }
58
87
 
88
+ async ask(question, options = {}) {
89
+ return this.chat(question, options);
90
+ }
91
+
59
92
  getHistory() {
60
93
  return this.history;
61
94
  }
62
95
 
63
96
  clearHistory() {
64
97
  this.history = [];
65
- return 'History cleared!';
98
+ this.saveHistory();
99
+ return 'History cleared successfully';
100
+ }
101
+
102
+ getHistoryByRole(role) {
103
+ return this.history.filter(entry => entry.role === role);
104
+ }
105
+
106
+ getLastMessage() {
107
+ return this.history.length > 0 ? this.history[this.history.length - 1] : null;
108
+ }
109
+
110
+ saveHistory() {
111
+ try {
112
+ fs.writeFileSync(this.configPath, JSON.stringify(this.history, null, 2));
113
+ } catch (error) {
114
+ console.log(chalk.red(`Failed to save history: ${error.message}`));
115
+ }
66
116
  }
67
117
 
68
- async askQuestion(question) {
69
- const response = await this.chat(question);
70
- return response;
118
+ loadHistory() {
119
+ try {
120
+ if (fs.existsSync(this.configPath)) {
121
+ const data = fs.readFileSync(this.configPath, 'utf8');
122
+ this.history = JSON.parse(data);
123
+ }
124
+ } catch (error) {
125
+ console.log(chalk.red(`Failed to load history: ${error.message}`));
126
+ this.history = [];
127
+ }
128
+ }
129
+
130
+ async exportHistory(format = 'json') {
131
+ if (format === 'json') {
132
+ return JSON.stringify(this.history, null, 2);
133
+ } else if (format === 'txt') {
134
+ let text = '';
135
+ for (const entry of this.history) {
136
+ text += `[${entry.timestamp}] ${entry.role.toUpperCase()}: ${entry.content}\n\n`;
137
+ }
138
+ return text;
139
+ }
140
+ return 'Unsupported format. Use json or txt';
141
+ }
142
+
143
+ async setApiKey(apiKey) {
144
+ if (!apiKey || apiKey.trim() === '') {
145
+ return 'Error: API key cannot be empty';
146
+ }
147
+ this.apiKey = apiKey;
148
+ this.provider = new GroqProvider(this.apiKey);
149
+ return 'API key updated successfully';
71
150
  }
72
151
  }
73
152
 
@@ -0,0 +1,120 @@
1
+ const Groq = require('groq-sdk');
2
+
3
+ class GroqProvider {
4
+ constructor(apiKey) {
5
+ if (!apiKey) {
6
+ throw new Error('API Key is required. Get your API key at: https://console.groq.com/keys');
7
+ }
8
+ this.client = new Groq({ apiKey });
9
+ this.model = "llama3-8b-8192";
10
+ this.availableModels = [
11
+ "llama3-8b-8192",
12
+ "llama3-70b-8192",
13
+ "mixtral-8x7b-32768",
14
+ "gemma2-9b-it"
15
+ ];
16
+ }
17
+
18
+ setModel(modelName) {
19
+ if (this.availableModels.includes(modelName)) {
20
+ this.model = modelName;
21
+ return true;
22
+ }
23
+ return false;
24
+ }
25
+
26
+ getModels() {
27
+ return this.availableModels;
28
+ }
29
+
30
+ async chat(message, options = {}) {
31
+ try {
32
+ const messages = [];
33
+
34
+ if (options.systemPrompt) {
35
+ messages.push({
36
+ role: "system",
37
+ content: options.systemPrompt
38
+ });
39
+ }
40
+
41
+ messages.push({
42
+ role: "user",
43
+ content: message
44
+ });
45
+
46
+ const completion = await this.client.chat.completions.create({
47
+ messages: messages,
48
+ model: options.model || this.model,
49
+ temperature: options.temperature || 0.7,
50
+ max_tokens: options.maxTokens || 2048,
51
+ top_p: options.topP || 1,
52
+ stop: options.stop || null
53
+ });
54
+
55
+ if (!completion.choices || completion.choices.length === 0) {
56
+ throw new Error('No response from API');
57
+ }
58
+
59
+ return completion.choices[0].message.content || "No response content";
60
+
61
+ } catch (error) {
62
+ if (error.status === 401) {
63
+ throw new Error('Invalid API key. Please check your GROQ_API_KEY');
64
+ } else if (error.status === 429) {
65
+ throw new Error('Rate limit exceeded. Please wait a moment and try again');
66
+ } else if (error.status === 404) {
67
+ throw new Error('Model not found. Please check the model name');
68
+ } else {
69
+ throw new Error(`API Error: ${error.message}`);
70
+ }
71
+ }
72
+ }
73
+
74
+ async streamChat(message, onChunk, options = {}) {
75
+ try {
76
+ const stream = await this.client.chat.completions.create({
77
+ messages: [{ role: "user", content: message }],
78
+ model: options.model || this.model,
79
+ temperature: options.temperature || 0.7,
80
+ max_tokens: options.maxTokens || 2048,
81
+ top_p: options.topP || 1,
82
+ stream: true,
83
+ });
84
+
85
+ for await (const chunk of stream) {
86
+ const content = chunk.choices[0]?.delta?.content || "";
87
+ if (content && onChunk) {
88
+ onChunk(content);
89
+ }
90
+ }
91
+
92
+ } catch (error) {
93
+ if (error.status === 401) {
94
+ throw new Error('Invalid API key. Please check your GROQ_API_KEY');
95
+ } else if (error.status === 429) {
96
+ throw new Error('Rate limit exceeded. Please wait a moment and try again');
97
+ } else {
98
+ throw new Error(`Stream error: ${error.message}`);
99
+ }
100
+ }
101
+ }
102
+
103
+ async chatWithHistory(messages, options = {}) {
104
+ try {
105
+ const completion = await this.client.chat.completions.create({
106
+ messages: messages,
107
+ model: options.model || this.model,
108
+ temperature: options.temperature || 0.7,
109
+ max_tokens: options.maxTokens || 2048,
110
+ });
111
+
112
+ return completion.choices[0].message.content || "No response content";
113
+
114
+ } catch (error) {
115
+ throw new Error(`API Error: ${error.message}`);
116
+ }
117
+ }
118
+ }
119
+
120
+ module.exports = GroqProvider;
package/package.json CHANGED
@@ -1,34 +1,29 @@
1
1
  {
2
2
  "name": "@yamzzdev/aiyamz",
3
- "version": "1.0.1",
4
- "description": "AI chat package by yamzzdev - powered by Google Gemini (FREE)",
3
+ "version": "1.0.3",
4
+ "description": "AI chat package by yamzzdev - powered by Groq (FREE)",
5
5
  "main": "lib/index.js",
6
6
  "bin": {
7
- "aiyamz": "bin/aiyamz.js"
7
+ "aiyamz": "./bin/aiyamz.js"
8
8
  },
9
9
  "keywords": [
10
10
  "ai",
11
11
  "chat",
12
- "gemini",
12
+ "groq",
13
+ "llama",
13
14
  "yamzzdev",
14
- "gabut"
15
+ "gabut",
16
+ "cli"
15
17
  ],
16
18
  "author": "yamzzdev",
17
19
  "license": "MIT",
18
20
  "dependencies": {
19
- "@google/generative-ai": "^0.21.0",
20
21
  "chalk": "^4.1.2",
21
22
  "commander": "^12.1.0",
22
- "inquirer": "^8.2.6",
23
- "ora": "^5.4.1",
23
+ "dotenv": "^16.4.5",
24
24
  "figlet": "^1.7.0",
25
- "dotenv": "^16.4.5"
26
- },
27
- "directories": {
28
- "lib": "lib"
29
- },
30
- "scripts": {
31
- "test": "echo \"Error: no test specified\" && exit 1"
32
- },
33
- "type": "commonjs"
25
+ "groq-sdk": "^0.5.0",
26
+ "inquirer": "^8.2.6",
27
+ "ora": "^5.4.1"
28
+ }
34
29
  }
@@ -1,40 +0,0 @@
1
- const { GoogleGenerativeAI } = require('@google/generative-ai');
2
- const chalk = require('chalk');
3
-
4
- class GeminiProvider {
5
- constructor(apiKey) {
6
- if (!apiKey) {
7
- throw new Error('API Key is required! Get your API key at: https://aistudio.google.com/apikey');
8
- }
9
- this.genAI = new GoogleGenerativeAI(apiKey);
10
- this.model = this.genAI.getGenerativeModel({ model: "gemini-1.5-flash" });
11
- }
12
-
13
- async chat(message, options = {}) {
14
- try {
15
- const prompt = options.systemPrompt
16
- ? `${options.systemPrompt}\n\nUser: ${message}`
17
- : message;
18
-
19
- const result = await this.model.generateContent(prompt);
20
- const response = await result.response;
21
- return response.text();
22
- } catch (error) {
23
- throw new Error(`Gemini API Error: ${error.message}`);
24
- }
25
- }
26
-
27
- async streamChat(message, onChunk) {
28
- try {
29
- const result = await this.model.generateContentStream(message);
30
- for await (const chunk of result.stream) {
31
- const chunkText = chunk.text();
32
- if (onChunk) onChunk(chunkText);
33
- }
34
- } catch (error) {
35
- throw new Error(`Stream error: ${error.message}`);
36
- }
37
- }
38
- }
39
-
40
- module.exports = GeminiProvider;