ask-my-llm 1.1.4 → 1.1.6

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.
Files changed (4) hide show
  1. package/LICENSE +25 -0
  2. package/README.md +10 -2
  3. package/bin/ask-ai +37 -81
  4. package/package.json +12 -8
package/LICENSE ADDED
@@ -0,0 +1,25 @@
1
+ This is free and unencumbered software released into the public domain.
2
+
3
+ Anyone is free to copy, modify, publish, use, compile, sell, or
4
+ distribute this software, either in source code form or as a compiled
5
+ binary, for any purpose, commercial or non-commercial, and by any
6
+ means.
7
+
8
+ In jurisdictions that recognize copyright laws, the author or authors
9
+ of this software dedicate any and all copyright interest in the
10
+ software to the public domain. We make this dedication for the benefit
11
+ of the public at large and to the detriment of our heirs and
12
+ successors. We intend this dedication to be an overt act of
13
+ relinquishment in perpetuity of all present and future rights to this
14
+ software under copyright law.
15
+
16
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
17
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
18
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
19
+ IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR
20
+ OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
21
+ ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
22
+ OTHER DEALINGS IN THE SOFTWARE.
23
+
24
+ For more information, please refer to <https://unlicense.org>
25
+
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
@@ -21,7 +23,7 @@ Prompts for:
21
23
 
22
24
  Config saved to `~/.askairc`.
23
25
 
24
- ## Usage
26
+ ## TL;DR
25
27
 
26
28
  ```js
27
29
  const { ask, askAsync, getModel } = require("ask-my-llm");
@@ -33,7 +35,7 @@ console.log(response);
33
35
  // async
34
36
  askAsync("Hello").then(console.log);
35
37
 
36
- //misc
38
+ // other
37
39
  console.log(getModel()) // Returns currently used model e.g. `google/gemma-3-4b-it`
38
40
  ```
39
41
 
@@ -52,3 +54,9 @@ Sends a prompt to the configured AI and returns a Promise.
52
54
 
53
55
  - `prompt` - The message to send
54
56
  - Returns: Promise that resolves to AI response as string
57
+
58
+ ### getModel(): string
59
+
60
+ Gets current model used.
61
+
62
+ - Returns: raw model string.
package/bin/ask-ai CHANGED
@@ -1,6 +1,6 @@
1
1
  #!/usr/bin/env node
2
2
 
3
- const inquirer = require('inquirer');
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 { prompt } = await inquirer.prompt([{
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 { name } = await inquirer.prompt([{
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 answers = await inquirer.prompt([
80
- {
81
- type: 'input',
82
- name: 'baseApi',
83
- message: 'Base API URL:',
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 { name } = await inquirer.prompt([{
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 { name } = await inquirer.prompt([{
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 answers = await inquirer.prompt([
131
- {
132
- type: 'input',
133
- name: 'baseApi',
134
- message: 'Base API URL:',
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 { name } = await inquirer.prompt([{
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/package.json CHANGED
@@ -1,17 +1,21 @@
1
1
  {
2
2
  "name": "ask-my-llm",
3
- "version": "1.1.4",
4
- "description": "Oversimplified AI usage npm module",
3
+ "version": "1.1.6",
4
+ "description": "Oversimplified, zero-dependency AI usage npm module",
5
5
  "main": "index.js",
6
6
  "bin": {
7
- "ask-my-llm": "./bin/ask-ai"
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": ["ai", "openai", "chatgpt", "llm"],
13
- "license": "MIT",
14
- "dependencies": {
15
- "inquirer": "^8.2.5"
16
- }
12
+ "keywords": [
13
+ "ai",
14
+ "openai",
15
+ "chatgpt",
16
+ "llm",
17
+ "zero-dependency"
18
+ ],
19
+ "license": "unlicense",
20
+ "dependencies": {}
17
21
  }