viho 0.0.2 → 0.0.4

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 +1,203 @@
1
- ## viho
1
+ # viho
2
+
3
+ A lightweight CLI tool for managing and chatting with AI models.
4
+
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
+
8
+ ## Features
9
+
10
+ - Multiple AI model management
11
+ - Interactive chat with streaming responses
12
+ - Support for thinking mode (enabled/disabled/auto)
13
+ - Configurable API endpoints (OpenAI, Anthropic, custom providers)
14
+ - Default model configuration
15
+ - Simple and intuitive CLI interface
16
+ - Persistent configuration storage
17
+
18
+ ## Installation
19
+
20
+ Install globally via npm:
21
+
22
+ ```bash
23
+ npm install -g viho
24
+ ```
25
+
26
+ ## Requirements
27
+
28
+ - Node.js >= 18.0.0
29
+
30
+ ## Quick Start
31
+
32
+ 1. Add your first AI model:
33
+
34
+ ```bash
35
+ viho model add
36
+ ```
37
+
38
+ 2. Set it as default:
39
+
40
+ ```bash
41
+ viho model default
42
+ ```
43
+
44
+ 3. Start chatting:
45
+
46
+ ```bash
47
+ viho chat
48
+ ```
49
+
50
+ ## Commands
51
+
52
+ ### Model Management
53
+
54
+ #### `viho model add`
55
+
56
+ Add a new AI model configuration interactively.
57
+
58
+ You'll be prompted to enter:
59
+
60
+ - Model name (a custom identifier)
61
+ - API key
62
+ - Base URL (e.g., https://api.openai.com/v1)
63
+ - Model ID (e.g., gpt-4, claude-3-5-sonnet-20241022)
64
+ - Thinking mode (enabled/disabled/auto)
65
+
66
+ ```bash
67
+ viho model add
68
+ ```
69
+
70
+ #### `viho model list`
71
+
72
+ List all configured models:
73
+
74
+ ```bash
75
+ viho model list
76
+ ```
77
+
78
+ #### `viho model remove`
79
+
80
+ Remove a model configuration:
81
+
82
+ ```bash
83
+ viho model remove
84
+ ```
85
+
86
+ #### `viho model default`
87
+
88
+ Set a default model for chat sessions:
89
+
90
+ ```bash
91
+ viho model default
92
+ ```
93
+
94
+ ### Chat
95
+
96
+ #### `viho chat [modelName]`
97
+
98
+ Start an interactive chat session with an AI model.
99
+
100
+ If no model name is provided, uses the default model:
101
+
102
+ ```bash
103
+ viho chat
104
+ ```
105
+
106
+ Or specify a model explicitly:
107
+
108
+ ```bash
109
+ viho chat mymodel
110
+ ```
111
+
112
+ The chat interface includes:
113
+
114
+ - Editor-based question input
115
+ - Streaming responses
116
+ - Visual thinking process (when enabled)
117
+ - Colored output for better readability
118
+
119
+ ## Configuration
120
+
121
+ Configuration is stored in `~/viho.json`. You can manage all settings through the CLI commands.
122
+
123
+ ### Example Configuration Structure
124
+
125
+ ```json
126
+ {
127
+ "mymodel": {
128
+ "modelName": "mymodel",
129
+ "apiKey": "your-api-key",
130
+ "baseURL": "https://api.openai.com/v1",
131
+ "modelID": "gpt-4",
132
+ "modelThinking": "auto"
133
+ },
134
+ "default": "mymodel"
135
+ }
136
+ ```
137
+
138
+ ## Supported Providers
139
+
140
+ viho works with any OpenAI-compatible API, including:
141
+
142
+ - OpenAI (GPT-4, GPT-3.5, etc.)
143
+ - Anthropic Claude (via compatible endpoints)
144
+ - Custom LLM providers with OpenAI-compatible APIs
145
+
146
+ ## Examples
147
+
148
+ ### Adding an OpenAI Model
149
+
150
+ ```bash
151
+ viho model add
152
+ # Enter model name: gpt4
153
+ # Enter API key: sk-...
154
+ # Enter base URL: https://api.openai.com/v1
155
+ # Enter model ID: gpt-4
156
+ # Thinking mode: disabled
157
+ ```
158
+
159
+ ### Adding a Claude Model
160
+
161
+ ```bash
162
+ viho model add
163
+ # Enter model name: claude
164
+ # Enter API key: your-anthropic-key
165
+ # Enter base URL: https://api.anthropic.com
166
+ # Enter model ID: claude-3-5-sonnet-20241022
167
+ # Thinking mode: auto
168
+ ```
169
+
170
+ ### Setting Up for First Use
171
+
172
+ ```bash
173
+ # Add a model
174
+ viho model add
175
+
176
+ # Set it as default
177
+ viho model default
178
+
179
+ # Start chatting
180
+ viho chat
181
+ ```
182
+
183
+ ## Dependencies
184
+
185
+ - [qiao-cli](https://www.npmjs.com/package/qiao-cli) - CLI utilities
186
+ - [qiao-config](https://www.npmjs.com/package/qiao-config) - Configuration management
187
+ - [qiao-llm](https://www.npmjs.com/package/qiao-llm) - LLM integration
188
+
189
+ ## License
190
+
191
+ MIT
192
+
193
+ ## Author
194
+
195
+ uikoo9 <uikoo9@qq.com>
196
+
197
+ ## Issues
198
+
199
+ Report issues at: https://github.com/uikoo9/viho/issues
200
+
201
+ ## Homepage
202
+
203
+ https://github.com/uikoo9/viho
package/bin/util.js ADDED
@@ -0,0 +1,17 @@
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
+ };
@@ -0,0 +1,97 @@
1
+ // qiao
2
+ const cli = require('qiao-cli');
3
+
4
+ // llm
5
+ const LLM = require('qiao-llm');
6
+
7
+ // db
8
+ const { getDB } = require('./util.js');
9
+ const db = getDB();
10
+
11
+ // cmd
12
+ cli.cmd
13
+ .command('chat [modelName]')
14
+ .description('Chat with an AI model')
15
+ .action(async (modelName) => {
16
+ if (!modelName) {
17
+ const defaultModel = await db.config('default');
18
+ if (!defaultModel) {
19
+ console.log(cli.colors.red('No default model set. Use: viho model default'));
20
+ return;
21
+ }
22
+
23
+ modelName = defaultModel;
24
+ }
25
+
26
+ // check
27
+ const model = await db.config(modelName);
28
+ if (!model) {
29
+ console.log(cli.colors.red(`Model not found: ${modelName}`));
30
+ return;
31
+ }
32
+
33
+ // init
34
+ const llm = LLM({
35
+ apiKey: model.apiKey,
36
+ baseURL: model.baseURL,
37
+ });
38
+
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();
54
+
55
+ // 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);
97
+ });
@@ -0,0 +1,185 @@
1
+ // qiao
2
+ const cli = require('qiao-cli');
3
+
4
+ // db
5
+ const { getDB } = require('./util.js');
6
+ const db = getDB();
7
+
8
+ // actions
9
+ const actions = ['add', 'list', 'remove', 'default'];
10
+
11
+ // model
12
+ cli.cmd
13
+ .command('model <action>')
14
+ .description('Manage AI models')
15
+ .action((action) => {
16
+ if (!actions.includes(action)) {
17
+ console.log(cli.colors.red('Invalid action. Use: add, list, remove, default'));
18
+ return;
19
+ }
20
+
21
+ // actions
22
+ if (action === 'add') modelAdd();
23
+ if (action === 'list') modelList();
24
+ if (action === 'remove') modelRemove();
25
+ if (action === 'default') modelDefault();
26
+ });
27
+
28
+ /**
29
+ * modelAdd
30
+ * @returns
31
+ */
32
+ async function modelAdd() {
33
+ try {
34
+ // q a
35
+ const questions = [
36
+ {
37
+ type: 'input',
38
+ name: 'modelName',
39
+ message: 'Enter model name:',
40
+ },
41
+ {
42
+ type: 'input',
43
+ name: 'apiKey',
44
+ message: 'Enter API key:',
45
+ },
46
+ {
47
+ type: 'input',
48
+ name: 'baseURL',
49
+ message: 'Enter base URL:',
50
+ },
51
+ {
52
+ type: 'input',
53
+ name: 'modelID',
54
+ message: 'Enter model ID:',
55
+ },
56
+ {
57
+ type: 'list',
58
+ name: 'modelThinking',
59
+ message: 'Thinking mode:',
60
+ choices: ['enabled', 'disabled', 'auto'],
61
+ },
62
+ ];
63
+ const answers = await cli.ask(questions);
64
+ console.log();
65
+
66
+ // check
67
+ const dbKey = answers.modelName;
68
+ const dbValue = await db.config(dbKey);
69
+ if (dbValue) {
70
+ console.log(cli.colors.red('Model name already exists'));
71
+ return;
72
+ }
73
+
74
+ // set
75
+ await db.config(dbKey, answers);
76
+ console.log(cli.colors.green('Model added'));
77
+ console.log();
78
+
79
+ // list
80
+ const all = await db.all();
81
+ console.log(all);
82
+ } catch (e) {
83
+ console.log(cli.colors.red('Error: Failed to add model'));
84
+ console.log();
85
+ console.log(e);
86
+ }
87
+ }
88
+
89
+ /**
90
+ * modelList
91
+ */
92
+ async function modelList() {
93
+ try {
94
+ // list
95
+ const all = await db.all();
96
+ console.log(cli.colors.cyan('Configured models:'));
97
+ console.log();
98
+ console.log(all);
99
+ } catch (e) {
100
+ console.log(cli.colors.red('Error: Failed to list models'));
101
+ console.log();
102
+
103
+ console.log(e);
104
+ }
105
+ }
106
+
107
+ /**
108
+ * modelRemove
109
+ */
110
+ async function modelRemove() {
111
+ try {
112
+ // q a
113
+ const questions = [
114
+ {
115
+ type: 'input',
116
+ name: 'modelName',
117
+ message: 'Enter model name to remove:',
118
+ },
119
+ ];
120
+ const answers = await cli.ask(questions);
121
+ console.log();
122
+
123
+ // del
124
+ const dbKey = answers.modelName;
125
+ await db.config(dbKey, null);
126
+ console.log(cli.colors.green('Model removed'));
127
+ console.log();
128
+
129
+ // list
130
+ const all = await db.all();
131
+ console.log(all);
132
+ } catch (e) {
133
+ console.log(cli.colors.red('Error: Failed to remove model'));
134
+ console.log();
135
+
136
+ console.log(e);
137
+ }
138
+ }
139
+
140
+ /**
141
+ * modelDefault
142
+ * @returns
143
+ */
144
+ async function modelDefault() {
145
+ try {
146
+ // q a
147
+ const questions = [
148
+ {
149
+ type: 'input',
150
+ name: 'modelName',
151
+ message: 'Enter default model name:',
152
+ },
153
+ ];
154
+ const answers = await cli.ask(questions);
155
+ console.log();
156
+
157
+ // get keys
158
+ const all = await db.all();
159
+ const keys = Object.keys(all);
160
+
161
+ // check keys
162
+ if (!keys || !keys.length) {
163
+ console.log(cli.colors.red('No models found. Add one first: viho model add'));
164
+ console.log();
165
+ return;
166
+ }
167
+
168
+ // check model
169
+ if (!keys.includes(answers.modelName)) {
170
+ console.log(cli.colors.red('Model not found. Available models:'));
171
+ console.log();
172
+ console.log(all);
173
+ return;
174
+ }
175
+
176
+ // set
177
+ await db.config('default', answers.modelName);
178
+ console.log(cli.colors.green(`Default model: ${answers.modelName}`));
179
+ console.log();
180
+ } catch (e) {
181
+ console.log(cli.colors.red('Error: Failed to set default model'));
182
+ console.log();
183
+ console.log(e);
184
+ }
185
+ }
package/bin/viho.js CHANGED
@@ -4,7 +4,9 @@
4
4
  const cli = require('qiao-cli');
5
5
 
6
6
  // cmds
7
- require('./sshs-version.js');
7
+ require('./viho-model.js');
8
+ require('./viho-chat.js');
9
+ require('./viho-version.js');
8
10
 
9
11
  // parse
10
12
  cli.cmd.parse(process.argv);
package/package.json CHANGED
@@ -1,8 +1,19 @@
1
1
  {
2
2
  "name": "viho",
3
- "version": "0.0.2",
4
- "description": "",
5
- "keywords": [],
3
+ "version": "0.0.4",
4
+ "description": "A lightweight CLI tool for managing and chatting with AI models",
5
+ "keywords": [
6
+ "ai",
7
+ "llm",
8
+ "chat",
9
+ "cli",
10
+ "chatgpt",
11
+ "anthropic",
12
+ "openai",
13
+ "ai-assistant",
14
+ "command-line",
15
+ "terminal"
16
+ ],
6
17
  "author": "uikoo9 <uikoo9@qq.com>",
7
18
  "license": "MIT",
8
19
  "homepage": "https://github.com/uikoo9/viho#readme",
@@ -22,10 +33,12 @@
22
33
  "README.md"
23
34
  ],
24
35
  "engines": {
25
- "node": ">=14.0.0"
36
+ "node": ">=18.0.0"
26
37
  },
27
38
  "dependencies": {
28
- "qiao-cli": "^5.0.0"
39
+ "qiao-cli": "^5.0.0",
40
+ "qiao-config": "^5.0.1",
41
+ "qiao-llm": "^0.2.5"
29
42
  },
30
- "gitHead": "843b0782665eb81e060b98e4926452843886359c"
43
+ "gitHead": "08434f296e9d87e8ae6dcb2720989edbc414841e"
31
44
  }