viho 0.0.4 → 0.0.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.
package/README.md CHANGED
@@ -1,14 +1,21 @@
1
- # viho
1
+ <p align="center">
2
+ <img src="./logo.png" alt="viho logo" width="200"/>
3
+ </p>
2
4
 
3
- A lightweight CLI tool for managing and chatting with AI models.
5
+ <h1 align="center">viho</h1>
4
6
 
5
- [![npm version](https://img.shields.io/npm/v/viho.svg)](https://www.npmjs.com/package/viho)
6
- [![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](https://opensource.org/licenses/MIT)
7
+ <p align="center">A lightweight CLI tool for managing and interacting with AI models.</p>
8
+
9
+ <p align="center">
10
+ <a href="https://www.npmjs.com/package/viho"><img src="https://img.shields.io/npm/v/viho.svg" alt="npm version"></a>
11
+ <a href="https://opensource.org/licenses/MIT"><img src="https://img.shields.io/badge/License-MIT-yellow.svg" alt="License: MIT"></a>
12
+ </p>
7
13
 
8
14
  ## Features
9
15
 
10
16
  - Multiple AI model management
11
- - Interactive chat with streaming responses
17
+ - Interactive Q&A with streaming responses
18
+ - Continuous chat sessions for multi-turn conversations
12
19
  - Support for thinking mode (enabled/disabled/auto)
13
20
  - Configurable API endpoints (OpenAI, Anthropic, custom providers)
14
21
  - Default model configuration
@@ -41,10 +48,10 @@ viho model add
41
48
  viho model default
42
49
  ```
43
50
 
44
- 3. Start chatting:
51
+ 3. Start asking questions:
45
52
 
46
53
  ```bash
47
- viho chat
54
+ viho ask
48
55
  ```
49
56
 
50
57
  ## Commands
@@ -91,31 +98,56 @@ Set a default model for chat sessions:
91
98
  viho model default
92
99
  ```
93
100
 
94
- ### Chat
101
+ ### Ask
95
102
 
96
- #### `viho chat [modelName]`
103
+ #### `viho ask [modelName]`
97
104
 
98
- Start an interactive chat session with an AI model.
105
+ Ask a question to an AI model.
99
106
 
100
107
  If no model name is provided, uses the default model:
101
108
 
102
109
  ```bash
103
- viho chat
110
+ viho ask
104
111
  ```
105
112
 
106
113
  Or specify a model explicitly:
107
114
 
108
115
  ```bash
109
- viho chat mymodel
116
+ viho ask mymodel
110
117
  ```
111
118
 
112
- The chat interface includes:
119
+ The interface includes:
113
120
 
114
121
  - Editor-based question input
115
122
  - Streaming responses
116
123
  - Visual thinking process (when enabled)
117
124
  - Colored output for better readability
118
125
 
126
+ ### Chat
127
+
128
+ #### `viho chat [modelName]`
129
+
130
+ Start a continuous chat session with an AI model for multi-turn conversations.
131
+
132
+ If no model name is provided, uses the default model:
133
+
134
+ ```bash
135
+ viho chat
136
+ ```
137
+
138
+ Or specify a model explicitly:
139
+
140
+ ```bash
141
+ viho chat mymodel
142
+ ```
143
+
144
+ The chat session runs in a loop, allowing you to ask multiple questions continuously without restarting the command. Each question uses the same model configuration but starts a fresh conversation context.
145
+
146
+ **Note:** The main difference between `viho ask` and `viho chat`:
147
+
148
+ - `viho ask` - Single question, exits after receiving the answer
149
+ - `viho chat` - Continuous loop, keeps asking for new questions until manually stopped (Ctrl+C)
150
+
119
151
  ## Configuration
120
152
 
121
153
  Configuration is stored in `~/viho.json`. You can manage all settings through the CLI commands.
@@ -176,8 +208,8 @@ viho model add
176
208
  # Set it as default
177
209
  viho model default
178
210
 
179
- # Start chatting
180
- viho chat
211
+ # Start asking questions
212
+ viho ask
181
213
  ```
182
214
 
183
215
  ## Dependencies
@@ -0,0 +1,47 @@
1
+ // qiao
2
+ const cli = require('qiao-cli');
3
+
4
+ // llm
5
+ const LLM = require('qiao-llm');
6
+
7
+ // util
8
+ const { ask } = require('../src/llm.js');
9
+ const { getModels } = require('../src/model.js');
10
+ const { getDB, printLogo } = require('../src/util.js');
11
+ const db = getDB();
12
+
13
+ // cmd
14
+ cli.cmd
15
+ .command('ask [modelName]')
16
+ .description('Ask a question to an AI model')
17
+ .action(async (modelName) => {
18
+ if (!modelName) {
19
+ const defaultModel = await db.config('default');
20
+ if (!defaultModel) {
21
+ console.log(cli.colors.red('No default model set. Use: viho model default'));
22
+ return;
23
+ }
24
+
25
+ modelName = defaultModel;
26
+ }
27
+
28
+ // check
29
+ const models = await getModels(db);
30
+ const model = models.find((m) => m.modelName === modelName);
31
+ if (!model) {
32
+ console.log(cli.colors.red(`Model not found: ${modelName}`));
33
+ return;
34
+ }
35
+
36
+ // init
37
+ const llm = LLM({
38
+ apiKey: model.apiKey,
39
+ baseURL: model.baseURL,
40
+ });
41
+
42
+ // logo
43
+ printLogo();
44
+
45
+ // ask
46
+ await ask(llm, model);
47
+ });
package/bin/viho-chat.js CHANGED
@@ -4,14 +4,16 @@ const cli = require('qiao-cli');
4
4
  // llm
5
5
  const LLM = require('qiao-llm');
6
6
 
7
- // db
8
- const { getDB } = require('./util.js');
7
+ // util
8
+ const { ask } = require('../src/llm.js');
9
+ const { getModels } = require('../src/model.js');
10
+ const { getDB, printLogo } = require('../src/util.js');
9
11
  const db = getDB();
10
12
 
11
13
  // cmd
12
14
  cli.cmd
13
15
  .command('chat [modelName]')
14
- .description('Chat with an AI model')
16
+ .description('Start a continuous chat session with an AI model')
15
17
  .action(async (modelName) => {
16
18
  if (!modelName) {
17
19
  const defaultModel = await db.config('default');
@@ -24,7 +26,8 @@ cli.cmd
24
26
  }
25
27
 
26
28
  // check
27
- const model = await db.config(modelName);
29
+ const models = await getModels(db);
30
+ const model = models.find((m) => m.modelName === modelName);
28
31
  if (!model) {
29
32
  console.log(cli.colors.red(`Model not found: ${modelName}`));
30
33
  return;
@@ -36,62 +39,14 @@ cli.cmd
36
39
  baseURL: model.baseURL,
37
40
  });
38
41
 
39
- // ask
40
- const questions = [
41
- {
42
- type: 'editor',
43
- name: 'content',
44
- message: 'Your question:',
45
- },
46
- ];
47
- const answers = await cli.ask(questions);
48
-
49
- // answers
50
- console.log();
51
- console.log(cli.colors.gray('Question:'));
52
- console.log(cli.colors.gray(answers.content));
53
- console.log();
42
+ // logo
43
+ printLogo();
44
+ console.log(cli.colors.cyan(`Welcome to viho chat! Using model: ${modelName}`));
45
+ console.log(cli.colors.gray('Press Ctrl+C to exit\n'));
54
46
 
55
47
  // chat
56
- const chatOptions = {
57
- model: model.modelID,
58
- messages: [
59
- { role: 'system', content: 'You are a helpful AI assistant' },
60
- { role: 'user', content: answers.content },
61
- ],
62
- thinking: {
63
- type: model.modelThinking,
64
- },
65
- };
66
-
67
- // callback options
68
- const callbackOptions = {
69
- firstThinkingCallback: () => {
70
- console.log();
71
- console.log(cli.colors.gray('[Thinking...]'));
72
- console.log();
73
- },
74
- thinkingCallback: (msg) => {
75
- process.stdout.write(cli.colors.gray(msg));
76
- },
77
- firstContentCallback: () => {
78
- console.log();
79
- console.log(cli.colors.cyan('[Response]'));
80
- console.log();
81
- },
82
- contentCallback: (msg) => {
83
- process.stdout.write(msg);
84
- },
85
- endCallback: () => {
86
- console.log();
87
- },
88
- errorCallback: (error) => {
89
- console.log();
90
- console.log(cli.colors.red('Error:'));
91
- console.log(error);
92
- },
93
- };
94
-
95
- // go
96
- await llm.chatWithStreaming(chatOptions, callbackOptions);
48
+ let keepChatting = true;
49
+ while (keepChatting) {
50
+ await ask(llm, model);
51
+ }
97
52
  });
package/bin/viho-model.js CHANGED
@@ -1,8 +1,9 @@
1
1
  // qiao
2
2
  const cli = require('qiao-cli');
3
3
 
4
- // db
5
- const { getDB } = require('./util.js');
4
+ // util
5
+ const { getModels, setModels } = require('../src/model.js');
6
+ const { getDB, printLogo } = require('../src/util.js');
6
7
  const db = getDB();
7
8
 
8
9
  // actions
@@ -64,21 +65,23 @@ async function modelAdd() {
64
65
  console.log();
65
66
 
66
67
  // check
67
- const dbKey = answers.modelName;
68
- const dbValue = await db.config(dbKey);
69
- if (dbValue) {
68
+ const modelName = answers.modelName;
69
+ const models = await getModels(db);
70
+ const isModelExists = models.some((model) => model.modelName === modelName);
71
+ if (isModelExists) {
70
72
  console.log(cli.colors.red('Model name already exists'));
71
73
  return;
72
74
  }
73
75
 
74
76
  // set
75
- await db.config(dbKey, answers);
77
+ models.push(answers);
78
+ await setModels(db, models);
76
79
  console.log(cli.colors.green('Model added'));
77
80
  console.log();
78
81
 
79
82
  // list
80
- const all = await db.all();
81
- console.log(all);
83
+ const allModels = await getModels(db);
84
+ console.log(allModels);
82
85
  } catch (e) {
83
86
  console.log(cli.colors.red('Error: Failed to add model'));
84
87
  console.log();
@@ -91,11 +94,14 @@ async function modelAdd() {
91
94
  */
92
95
  async function modelList() {
93
96
  try {
97
+ // logo
98
+ printLogo();
99
+
94
100
  // list
95
- const all = await db.all();
101
+ const models = await getModels(db);
96
102
  console.log(cli.colors.cyan('Configured models:'));
97
103
  console.log();
98
- console.log(all);
104
+ console.log(models);
99
105
  } catch (e) {
100
106
  console.log(cli.colors.red('Error: Failed to list models'));
101
107
  console.log();
@@ -121,14 +127,34 @@ async function modelRemove() {
121
127
  console.log();
122
128
 
123
129
  // del
124
- const dbKey = answers.modelName;
125
- await db.config(dbKey, null);
130
+ const models = await getModels(db);
131
+ const modelNameToRemove = answers.modelName;
132
+
133
+ // check if model exists
134
+ const modelExists = models.some((model) => model.modelName === modelNameToRemove);
135
+ if (!modelExists) {
136
+ console.log(cli.colors.red(`Model not found: ${modelNameToRemove}`));
137
+ console.log();
138
+ return;
139
+ }
140
+
141
+ const newModels = models.filter((model) => model.modelName !== modelNameToRemove);
142
+ await setModels(db, newModels);
143
+
144
+ // clear default if removed model was default
145
+ const defaultModel = await db.config('default');
146
+ if (defaultModel === modelNameToRemove) {
147
+ await db.config('default', null);
148
+ console.log(cli.colors.yellow('Removed model was set as default. Please set a new default.'));
149
+ console.log();
150
+ }
151
+
126
152
  console.log(cli.colors.green('Model removed'));
127
153
  console.log();
128
154
 
129
155
  // list
130
- const all = await db.all();
131
- console.log(all);
156
+ const allModels = await getModels(db);
157
+ console.log(allModels);
132
158
  } catch (e) {
133
159
  console.log(cli.colors.red('Error: Failed to remove model'));
134
160
  console.log();
@@ -155,8 +181,8 @@ async function modelDefault() {
155
181
  console.log();
156
182
 
157
183
  // get keys
158
- const all = await db.all();
159
- const keys = Object.keys(all);
184
+ const models = await getModels(db);
185
+ const keys = models.map((model) => model.modelName);
160
186
 
161
187
  // check keys
162
188
  if (!keys || !keys.length) {
@@ -169,7 +195,7 @@ async function modelDefault() {
169
195
  if (!keys.includes(answers.modelName)) {
170
196
  console.log(cli.colors.red('Model not found. Available models:'));
171
197
  console.log();
172
- console.log(all);
198
+ console.log(models);
173
199
  return;
174
200
  }
175
201
 
package/bin/viho.js CHANGED
@@ -5,6 +5,7 @@ const cli = require('qiao-cli');
5
5
 
6
6
  // cmds
7
7
  require('./viho-model.js');
8
+ require('./viho-ask.js');
8
9
  require('./viho-chat.js');
9
10
  require('./viho-version.js');
10
11
 
package/logo.png ADDED
Binary file
package/package.json CHANGED
@@ -1,10 +1,12 @@
1
1
  {
2
2
  "name": "viho",
3
- "version": "0.0.4",
4
- "description": "A lightweight CLI tool for managing and chatting with AI models",
3
+ "version": "0.0.6",
4
+ "description": "A lightweight CLI tool for managing and interacting with AI models",
5
5
  "keywords": [
6
6
  "ai",
7
7
  "llm",
8
+ "qa",
9
+ "ask",
8
10
  "chat",
9
11
  "cli",
10
12
  "chatgpt",
@@ -30,7 +32,8 @@
30
32
  "files": [
31
33
  "bin",
32
34
  "LICENSE",
33
- "README.md"
35
+ "README.md",
36
+ "logo.png"
34
37
  ],
35
38
  "engines": {
36
39
  "node": ">=18.0.0"
@@ -40,5 +43,5 @@
40
43
  "qiao-config": "^5.0.1",
41
44
  "qiao-llm": "^0.2.5"
42
45
  },
43
- "gitHead": "08434f296e9d87e8ae6dcb2720989edbc414841e"
46
+ "gitHead": "2a10a0acfc92501a023e93f7f268e6f8ad57f9fc"
44
47
  }
package/bin/util.js DELETED
@@ -1,17 +0,0 @@
1
- // os
2
- const os = require('os');
3
-
4
- // path
5
- const path = require('path');
6
-
7
- // db
8
- const DB = require('qiao-config');
9
-
10
- /**
11
- * getDB
12
- * @returns
13
- */
14
- exports.getDB = () => {
15
- const dbPath = path.resolve(os.homedir(), './viho.json');
16
- return DB(dbPath);
17
- };