ask-my-llm 1.1.5 → 1.1.7
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 +3 -1
- package/bin/ask-ai +37 -81
- package/index.js +4 -3
- package/package.json +11 -7
package/README.md
CHANGED
|
@@ -2,6 +2,8 @@
|
|
|
2
2
|
|
|
3
3
|
Oversimplified AI usage npm module.
|
|
4
4
|
|
|
5
|
+
**NEW:** Now ask-my-llm is fully zero dependency!
|
|
6
|
+
|
|
5
7
|
## Install
|
|
6
8
|
|
|
7
9
|
```bash
|
|
@@ -33,7 +35,7 @@ console.log(response);
|
|
|
33
35
|
// async
|
|
34
36
|
askAsync("Hello").then(console.log);
|
|
35
37
|
|
|
36
|
-
//
|
|
38
|
+
// other
|
|
37
39
|
console.log(getModel()) // Returns currently used model e.g. `google/gemma-3-4b-it`
|
|
38
40
|
```
|
|
39
41
|
|
package/bin/ask-ai
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
|
|
3
|
-
const
|
|
3
|
+
const readline = require('readline');
|
|
4
4
|
const fs = require('fs');
|
|
5
5
|
const path = require('path');
|
|
6
6
|
const { ask } = require('../index.js');
|
|
@@ -19,12 +19,27 @@ function saveConfig(config) {
|
|
|
19
19
|
fs.writeFileSync(CONFIG_PATH, JSON.stringify(config, null, 2));
|
|
20
20
|
}
|
|
21
21
|
|
|
22
|
+
function question(query, defaultValue) {
|
|
23
|
+
const rl = readline.createInterface({ input: process.stdin, output: process.stdout });
|
|
24
|
+
return new Promise(resolve => {
|
|
25
|
+
const text = defaultValue != null ? `${query} (${defaultValue}): ` : `${query}: `;
|
|
26
|
+
rl.question(text, answer => {
|
|
27
|
+
rl.close();
|
|
28
|
+
resolve(answer || defaultValue || '');
|
|
29
|
+
});
|
|
30
|
+
});
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
async function listQuestion(message, choices) {
|
|
34
|
+
console.log(`${message}:`);
|
|
35
|
+
choices.forEach((c, i) => console.log(` ${i + 1}) ${c}`));
|
|
36
|
+
const answer = await question('Enter number');
|
|
37
|
+
const idx = parseInt(answer, 10) - 1;
|
|
38
|
+
return choices[idx] || choices[0];
|
|
39
|
+
}
|
|
40
|
+
|
|
22
41
|
async function testConfig(config) {
|
|
23
|
-
const
|
|
24
|
-
type: 'input',
|
|
25
|
-
name: 'prompt',
|
|
26
|
-
message: 'Enter prompt:'
|
|
27
|
-
}]);
|
|
42
|
+
const prompt = await question('Enter prompt');
|
|
28
43
|
|
|
29
44
|
try {
|
|
30
45
|
console.log('Response:', ask(prompt));
|
|
@@ -35,7 +50,7 @@ async function testConfig(config) {
|
|
|
35
50
|
|
|
36
51
|
async function mainMenu() {
|
|
37
52
|
let config = loadConfig();
|
|
38
|
-
|
|
53
|
+
|
|
39
54
|
if (!config || !config.configs || Object.keys(config.configs).length === 0) {
|
|
40
55
|
console.log('No configs found. Creating first one...');
|
|
41
56
|
await addConfig({ current: null, configs: {} });
|
|
@@ -43,13 +58,7 @@ async function mainMenu() {
|
|
|
43
58
|
}
|
|
44
59
|
|
|
45
60
|
const choices = ['Add new config', 'Select config', 'Edit config', 'Remove config', 'Test config'];
|
|
46
|
-
|
|
47
|
-
const { action } = await inquirer.prompt([{
|
|
48
|
-
type: 'list',
|
|
49
|
-
name: 'action',
|
|
50
|
-
message: `Current: ${config.current}`,
|
|
51
|
-
choices
|
|
52
|
-
}]);
|
|
61
|
+
const action = await listQuestion(`Current: ${config.current}`, choices);
|
|
53
62
|
|
|
54
63
|
if (action === 'Add new config') {
|
|
55
64
|
await addConfig(config);
|
|
@@ -65,39 +74,18 @@ async function mainMenu() {
|
|
|
65
74
|
}
|
|
66
75
|
|
|
67
76
|
async function addConfig(config) {
|
|
68
|
-
const
|
|
69
|
-
type: 'input',
|
|
70
|
-
name: 'name',
|
|
71
|
-
message: 'Config name:'
|
|
72
|
-
}]);
|
|
77
|
+
const name = await question('Config name');
|
|
73
78
|
|
|
74
79
|
if (config.configs[name]) {
|
|
75
80
|
console.log('Config already exists. Edit it instead.');
|
|
76
81
|
return;
|
|
77
82
|
}
|
|
78
83
|
|
|
79
|
-
const
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
default: 'https://api.openai.com/v1'
|
|
85
|
-
},
|
|
86
|
-
{
|
|
87
|
-
type: 'input',
|
|
88
|
-
name: 'apiKey',
|
|
89
|
-
message: 'API Key (leave empty for none):',
|
|
90
|
-
default: ''
|
|
91
|
-
},
|
|
92
|
-
{
|
|
93
|
-
type: 'input',
|
|
94
|
-
name: 'model',
|
|
95
|
-
message: 'Model:',
|
|
96
|
-
default: 'gpt-3.5-turbo'
|
|
97
|
-
}
|
|
98
|
-
]);
|
|
99
|
-
|
|
100
|
-
config.configs[name] = answers;
|
|
84
|
+
const baseApi = await question('Base API URL', 'https://api.openai.com/v1');
|
|
85
|
+
const apiKey = await question('API Key (leave empty for none)', '');
|
|
86
|
+
const model = await question('Model', 'gpt-3.5-turbo');
|
|
87
|
+
|
|
88
|
+
config.configs[name] = { baseApi, apiKey, model };
|
|
101
89
|
config.current = name;
|
|
102
90
|
saveConfig(config);
|
|
103
91
|
console.log(`Config '${name}' saved.`);
|
|
@@ -105,12 +93,7 @@ async function addConfig(config) {
|
|
|
105
93
|
|
|
106
94
|
async function selectConfig(config) {
|
|
107
95
|
const names = Object.keys(config.configs);
|
|
108
|
-
const
|
|
109
|
-
type: 'list',
|
|
110
|
-
name: 'name',
|
|
111
|
-
message: 'Select config:',
|
|
112
|
-
choices: names
|
|
113
|
-
}]);
|
|
96
|
+
const name = await listQuestion('Select config', names);
|
|
114
97
|
|
|
115
98
|
config.current = name;
|
|
116
99
|
saveConfig(config);
|
|
@@ -119,36 +102,14 @@ async function selectConfig(config) {
|
|
|
119
102
|
|
|
120
103
|
async function editConfig(config) {
|
|
121
104
|
const names = Object.keys(config.configs);
|
|
122
|
-
const
|
|
123
|
-
type: 'list',
|
|
124
|
-
name: 'name',
|
|
125
|
-
message: 'Edit config:',
|
|
126
|
-
choices: names
|
|
127
|
-
}]);
|
|
105
|
+
const name = await listQuestion('Edit config', names);
|
|
128
106
|
|
|
129
107
|
const existing = config.configs[name];
|
|
130
|
-
const
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
default: existing.baseApi
|
|
136
|
-
},
|
|
137
|
-
{
|
|
138
|
-
type: 'input',
|
|
139
|
-
name: 'apiKey',
|
|
140
|
-
message: 'API Key (leave empty for none):',
|
|
141
|
-
default: existing.apiKey || ''
|
|
142
|
-
},
|
|
143
|
-
{
|
|
144
|
-
type: 'input',
|
|
145
|
-
name: 'model',
|
|
146
|
-
message: 'Model:',
|
|
147
|
-
default: existing.model
|
|
148
|
-
}
|
|
149
|
-
]);
|
|
150
|
-
|
|
151
|
-
config.configs[name] = answers;
|
|
108
|
+
const baseApi = await question('Base API URL', existing.baseApi);
|
|
109
|
+
const apiKey = await question('API Key (leave empty for none)', existing.apiKey || '');
|
|
110
|
+
const model = await question('Model', existing.model);
|
|
111
|
+
|
|
112
|
+
config.configs[name] = { baseApi, apiKey, model };
|
|
152
113
|
saveConfig(config);
|
|
153
114
|
console.log(`Config '${name}' updated.`);
|
|
154
115
|
}
|
|
@@ -160,12 +121,7 @@ async function removeConfig(config) {
|
|
|
160
121
|
return;
|
|
161
122
|
}
|
|
162
123
|
|
|
163
|
-
const
|
|
164
|
-
type: 'list',
|
|
165
|
-
name: 'name',
|
|
166
|
-
message: 'Remove config:',
|
|
167
|
-
choices: names
|
|
168
|
-
}]);
|
|
124
|
+
const name = await listQuestion('Remove config', names);
|
|
169
125
|
|
|
170
126
|
delete config.configs[name];
|
|
171
127
|
if (config.current === name) {
|
package/index.js
CHANGED
|
@@ -66,11 +66,11 @@ function ask(prompt, options) {
|
|
|
66
66
|
const args = [
|
|
67
67
|
'-s', '-S', '-X', 'POST',
|
|
68
68
|
...headerArgs,
|
|
69
|
-
'-d',
|
|
69
|
+
'-d', '@-',
|
|
70
70
|
url
|
|
71
71
|
];
|
|
72
72
|
|
|
73
|
-
const result = spawnSync('curl', args, { encoding: 'utf8' });
|
|
73
|
+
const result = spawnSync('curl', args, { encoding: 'utf8', input: postData });
|
|
74
74
|
|
|
75
75
|
if (result.error) throw result.error;
|
|
76
76
|
if (result.status !== 0) throw new Error('curl failed: ' + (result.stderr || result.stdout));
|
|
@@ -103,7 +103,7 @@ function askAsync(prompt, options) {
|
|
|
103
103
|
if (config.apiKey) {
|
|
104
104
|
headerArgs.push('-H', `Authorization: Bearer ${config.apiKey}`);
|
|
105
105
|
}
|
|
106
|
-
headerArgs.push('-d',
|
|
106
|
+
headerArgs.push('-d', '@-', url);
|
|
107
107
|
|
|
108
108
|
const child = spawn('curl', headerArgs, { encoding: 'utf8' });
|
|
109
109
|
let data = '';
|
|
@@ -111,6 +111,7 @@ function askAsync(prompt, options) {
|
|
|
111
111
|
|
|
112
112
|
child.stdout.on('data', chunk => data += chunk);
|
|
113
113
|
child.stderr.on('data', chunk => error += chunk);
|
|
114
|
+
child.stdin.end(postData);
|
|
114
115
|
child.on('close', code => {
|
|
115
116
|
if (code !== 0) {
|
|
116
117
|
reject(new Error('curl failed: ' + (error || data)));
|
package/package.json
CHANGED
|
@@ -1,17 +1,21 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "ask-my-llm",
|
|
3
|
-
"version": "1.1.
|
|
4
|
-
"description": "Oversimplified AI usage npm module",
|
|
3
|
+
"version": "1.1.7",
|
|
4
|
+
"description": "Oversimplified, zero-dependency AI usage npm module",
|
|
5
5
|
"main": "index.js",
|
|
6
6
|
"bin": {
|
|
7
|
-
"ask-my-llm": "
|
|
7
|
+
"ask-my-llm": "bin/ask-ai"
|
|
8
8
|
},
|
|
9
9
|
"scripts": {
|
|
10
10
|
"test": "echo \"Error: no test specified\" && exit 1"
|
|
11
11
|
},
|
|
12
|
-
"keywords": [
|
|
12
|
+
"keywords": [
|
|
13
|
+
"ai",
|
|
14
|
+
"openai",
|
|
15
|
+
"chatgpt",
|
|
16
|
+
"llm",
|
|
17
|
+
"zero-dependency"
|
|
18
|
+
],
|
|
13
19
|
"license": "unlicense",
|
|
14
|
-
"dependencies": {
|
|
15
|
-
"inquirer": "^8.2.5"
|
|
16
|
-
}
|
|
20
|
+
"dependencies": {}
|
|
17
21
|
}
|