viho-llm 1.0.6 → 1.0.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 CHANGED
@@ -4,7 +4,7 @@
4
4
 
5
5
  <h1 align="center">viho-llm</h1>
6
6
 
7
- <p align="center">Utility library for working with multiple LLM providers (Google Gemini and OpenAI), providing common tools and helpers for AI interactions.</p>
7
+ <p align="center">Multi-provider LLM library supporting Google Gemini and OpenAI compatible APIs.</p>
8
8
 
9
9
  ## Installation
10
10
 
@@ -12,511 +12,113 @@
12
12
  npm install viho-llm
13
13
  ```
14
14
 
15
- ## Prerequisites
15
+ ## Providers
16
16
 
17
- This library supports multiple LLM providers:
17
+ ### GeminiAPI
18
18
 
19
- ### Google Gemini AI
20
-
21
- 1. **Google AI Studio (GeminiAPI)** - For personal development and prototyping
22
- - Get an API key from [Google AI Studio](https://makersuite.google.com/app/apikey)
23
-
24
- 2. **Vertex AI (GeminiVertex)** - For enterprise applications with advanced features
25
- - Requires a Google Cloud project with Vertex AI enabled
26
- - Supports context caching for cost optimization
27
-
28
- ### OpenAI Compatible APIs
29
-
30
- **OpenAI API (OpenAIAPI)** - For OpenAI and compatible services
31
-
32
- - Supports official OpenAI API
33
- - Compatible with OpenAI-like APIs (e.g., DeepSeek, local LLMs)
34
- - Supports thinking/reasoning mode for compatible models
35
-
36
- ## Usage
37
-
38
- ### Basic Example with GeminiAPI
39
-
40
- Using Google AI Studio API Key (recommended for development):
19
+ Google AI Studio:
41
20
 
42
21
  ```javascript
43
22
  import { GeminiAPI } from 'viho-llm';
44
23
 
45
- // Initialize Gemini client with API Key
46
24
  const gemini = GeminiAPI({
47
- apiKey: 'your-google-api-key',
25
+ apiKey: 'your-api-key',
48
26
  modelName: 'gemini-pro',
49
27
  });
50
28
 
51
- // Send a chat message
52
29
  const response = await gemini.chat({
53
- contents: [
54
- {
55
- role: 'user',
56
- parts: [{ text: 'Hello, how are you?' }],
57
- },
58
- ],
30
+ contents: [{ role: 'user', parts: [{ text: 'Hello' }] }],
59
31
  });
60
-
61
- console.log(response);
62
32
  ```
63
33
 
64
- ### Basic Example with GeminiVertex
34
+ ### GeminiVertex
65
35
 
66
- Using Vertex AI (recommended for production):
36
+ Google Vertex AI with context caching support:
67
37
 
68
38
  ```javascript
69
39
  import { GeminiVertex } from 'viho-llm';
70
40
 
71
- // Initialize Gemini client with Vertex AI
72
41
  const gemini = GeminiVertex({
73
- projectId: 'your-gcp-project-id',
42
+ projectId: 'your-project-id',
74
43
  location: 'us-east1',
75
- modelName: 'gemini-pro',
44
+ modelName: 'gemini-1.5-flash-002',
76
45
  });
77
46
 
78
- // Send a chat message
47
+ // Chat
79
48
  const response = await gemini.chat({
80
- contents: [
81
- {
82
- role: 'user',
83
- parts: [{ text: 'Hello, how are you?' }],
84
- },
85
- ],
49
+ contents: [{ role: 'user', parts: [{ text: 'Hello' }] }],
86
50
  });
87
51
 
88
- console.log(response);
52
+ // Context caching (Vertex only)
53
+ await gemini.cacheAdd({
54
+ gsPath: 'gs://bucket/file.pdf',
55
+ systemPrompt: '...',
56
+ cacheName: 'my-cache',
57
+ cacheTTL: '3600s',
58
+ });
59
+ await gemini.cacheList();
60
+ await gemini.cacheUpdate(cacheName, { ttl: '7200s' });
89
61
  ```
90
62
 
91
- ### Basic Example with OpenAI API
63
+ ### OpenAIAPI
92
64
 
93
- Using OpenAI or OpenAI-compatible services:
65
+ OpenAI and compatible APIs (DeepSeek, Kimi, etc.):
94
66
 
95
67
  ```javascript
96
68
  import { OpenAIAPI } from 'viho-llm';
97
69
 
98
- // Initialize OpenAI client
99
70
  const openai = OpenAIAPI({
100
- apiKey: 'your-openai-api-key',
101
- baseURL: 'https://api.openai.com/v1', // or your custom endpoint
71
+ apiKey: 'your-api-key',
72
+ baseURL: 'https://api.openai.com/v1',
102
73
  });
103
74
 
104
- // Send a chat message (using native OpenAI API format)
105
75
  const response = await openai.chat({
106
76
  model: 'gpt-4o',
107
- messages: [
108
- { role: 'system', content: 'You are a helpful assistant.' },
109
- { role: 'user', content: 'Hello, how are you?' },
110
- ],
77
+ messages: [{ role: 'user', content: 'Hello' }],
111
78
  });
112
-
113
- console.log(response);
114
79
  ```
115
80
 
116
- ### Streaming Example
117
-
118
- All providers (GeminiAPI, GeminiVertex, and OpenAIAPI) support streaming responses:
81
+ ## Streaming
119
82
 
120
- #### Gemini Streaming
83
+ All providers support streaming via `chatWithStreaming`:
121
84
 
122
85
  ```javascript
123
- // Send a chat message with streaming
124
- await gemini.chatWithStreaming(
125
- {
126
- contents: [
127
- {
128
- role: 'user',
129
- parts: [{ text: 'Write a long story about AI' }],
130
- },
131
- ],
132
- },
133
- {
134
- beginCallback: () => {
135
- console.log('Stream started...');
136
- },
137
- firstContentCallback: () => {
138
- console.log('First chunk received!');
139
- },
140
- contentCallback: (content) => {
141
- process.stdout.write(content); // Print each chunk as it arrives
142
- },
143
- endCallback: () => {
144
- console.log('\nStream ended.');
145
- },
146
- errorCallback: (error) => {
147
- console.error('Error:', error);
148
- },
149
- },
150
- );
151
- ```
152
-
153
- #### OpenAI Streaming with Thinking Mode
154
-
155
- OpenAI streaming supports thinking/reasoning content for compatible models:
156
-
157
- ```javascript
158
- // Send a chat message with streaming (supports thinking mode)
159
86
  await openai.chatWithStreaming(
160
87
  {
161
88
  model: 'deepseek-reasoner',
162
- messages: [
163
- { role: 'system', content: 'You are a helpful assistant.' },
164
- { role: 'user', content: 'Explain how neural networks work' },
165
- ],
166
- thinking: {
167
- type: 'enabled', // Enable reasoning mode
168
- },
89
+ messages: [{ role: 'user', content: 'Hello' }],
169
90
  },
170
91
  {
171
- beginCallback: () => {
172
- console.log('Stream started...');
173
- },
174
- firstThinkingCallback: () => {
175
- console.log('\n[Thinking...]');
176
- },
177
- thinkingCallback: (thinking) => {
178
- process.stdout.write(thinking); // Print reasoning process
179
- },
180
- firstContentCallback: () => {
181
- console.log('\n[Response:]');
182
- },
183
- contentCallback: (content) => {
184
- process.stdout.write(content); // Print response content
185
- },
186
- endCallback: () => {
187
- console.log('\nStream ended.');
188
- },
189
- errorCallback: (error) => {
190
- console.error('Error:', error);
191
- },
92
+ beginCallback: () => {},
93
+ firstThinkingCallback: () => {}, // OpenAI only, for reasoning models
94
+ thinkingCallback: (text) => {}, // OpenAI only
95
+ firstContentCallback: () => {},
96
+ contentCallback: (text) => process.stdout.write(text),
97
+ endCallback: () => {},
98
+ errorCallback: (err) => {},
192
99
  },
193
100
  );
194
101
  ```
195
102
 
196
- ### Context Caching Example (Vertex AI Only)
103
+ ## Agents
197
104
 
198
- GeminiVertex supports context caching to reduce costs and latency when using large contexts:
105
+ Sequential agent runner with early break support:
199
106
 
200
107
  ```javascript
201
- import { GeminiVertex } from 'viho-llm';
202
-
203
- const gemini = GeminiVertex({
204
- projectId: 'your-gcp-project-id',
205
- location: 'us-east1',
206
- modelName: 'gemini-1.5-flash-002',
207
- });
208
-
209
- // Add a new cache
210
- const cache = await gemini.cacheAdd({
211
- gsPath: 'gs://your-bucket/large-document.pdf',
212
- systemPrompt: 'You are an expert at analyzing technical documents.',
213
- cacheName: 'my-document-cache',
214
- cacheTTL: '3600s', // 1 hour
215
- });
216
-
217
- console.log('Cache created:', cache.name);
218
-
219
- // List all caches
220
- const caches = await gemini.cacheList();
221
- console.log('Available caches:', caches);
222
-
223
- // Update cache TTL
224
- await gemini.cacheUpdate(cache.name, {
225
- ttl: '7200s', // Extend to 2 hours
226
- });
227
- ```
228
-
229
- ## API Reference
108
+ import { runAgents } from 'viho-llm';
230
109
 
231
- ### `GeminiAPI(options)`
232
-
233
- Creates a new Gemini client instance using Google AI Studio API.
234
-
235
- #### Parameters
236
-
237
- - `options` (Object) - Configuration options
238
- - `apiKey` (string) **required** - Your Google AI API key
239
- - `modelName` (string) **required** - Model name (e.g., 'gemini-pro', 'gemini-pro-vision')
240
-
241
- #### Returns
242
-
243
- Returns a Gemini client object with the following methods:
244
-
245
- ##### `client.chat(chatOptions)`
246
-
247
- Sends a chat request to the Gemini API.
248
-
249
- **Parameters:**
250
-
251
- - `chatOptions` (Object)
252
- - `contents` (Array) **required** - Array of message objects
253
- - `role` (string) - Either 'user' or 'model'
254
- - `parts` (Array) - Array of content parts
255
- - `text` (string) - The text content
256
-
257
- **Returns:**
258
-
259
- - (Promise\<string\>) - The generated text response
260
-
261
- **Example:**
262
-
263
- ```javascript
264
- const response = await gemini.chat({
265
- contents: [
266
- {
267
- role: 'user',
268
- parts: [{ text: 'Write a haiku about coding' }],
269
- },
270
- ],
271
- });
272
- ```
273
-
274
- ##### `client.chatWithStreaming(chatOptions, callbackOptions)`
275
-
276
- Sends a chat request to the Gemini API with streaming response.
277
-
278
- **Parameters:**
279
-
280
- - `chatOptions` (Object)
281
- - `contents` (Array) **required** - Array of message objects
282
- - `role` (string) - Either 'user' or 'model'
283
- - `parts` (Array) - Array of content parts
284
- - `text` (string) - The text content
285
-
286
- - `callbackOptions` (Object) - Callback functions for handling stream events
287
- - `beginCallback` (Function) - Called when the stream begins
288
- - `contentCallback` (Function) - Called for each content chunk received
289
- - Parameters: `content` (string) - The text chunk
290
- - `firstContentCallback` (Function) - Called when the first content chunk is received
291
- - `endCallback` (Function) - Called when the stream ends successfully
292
- - `errorCallback` (Function) - Called if an error occurs
293
- - Parameters: `error` (Error) - The error object
294
-
295
- **Returns:**
296
-
297
- - (Promise\<void\>) - Resolves when streaming completes
298
-
299
- **Example:**
300
-
301
- ```javascript
302
- await gemini.chatWithStreaming(
303
- {
304
- contents: [
305
- {
306
- role: 'user',
307
- parts: [{ text: 'Explain quantum computing' }],
308
- },
309
- ],
310
- },
110
+ await runAgents([
311
111
  {
312
- contentCallback: (chunk) => {
313
- console.log('Received:', chunk);
314
- },
315
- endCallback: () => {
316
- console.log('Done!');
317
- },
112
+ agentStartCallback: () => console.log('Agent 1 starting'),
113
+ agentRequestOptions: { llm: openai, modelName: 'gpt-4o', messages: [...], isJson: false, thinking: null },
114
+ agentEndCallback: (response) => { console.log(response); return false; },
115
+ agentBreakCallback: () => console.log('Breaking'), // optional
318
116
  },
319
- );
117
+ ]);
320
118
  ```
321
119
 
322
- ---
323
-
324
- ### `GeminiVertex(options)`
325
-
326
- Creates a new Gemini client instance using Vertex AI. Includes all features of GeminiAPI plus context caching support.
327
-
328
- #### Parameters
329
-
330
- - `options` (Object) - Configuration options
331
- - `projectId` (string) **required** - Your Google Cloud project ID
332
- - `location` (string) **required** - GCP region (e.g., 'us-east1', 'us-central1')
333
- - `modelName` (string) **required** - Model name (e.g., 'gemini-1.5-flash-002', 'gemini-1.5-pro-002')
334
-
335
- #### Returns
336
-
337
- Returns a Gemini client object with the following methods:
338
-
339
- ##### `client.chat(chatOptions)`
340
-
341
- Same as GeminiAPI.chat(). See above for details.
342
-
343
- ##### `client.chatWithStreaming(chatOptions, callbackOptions)`
344
-
345
- Same as GeminiAPI.chatWithStreaming(). See above for details.
346
-
347
- ##### `client.cacheAdd(cacheOptions)`
348
-
349
- Creates a new context cache for frequently used content.
350
-
351
- **Parameters:**
352
-
353
- - `cacheOptions` (Object)
354
- - `gsPath` (string) **required** - Google Cloud Storage path (e.g., 'gs://bucket/file.pdf')
355
- - `systemPrompt` (string) **required** - System instruction for the cached context
356
- - `cacheName` (string) **required** - Display name for the cache
357
- - `cacheTTL` (string) **required** - Time-to-live (e.g., '3600s' for 1 hour)
358
-
359
- **Returns:**
360
-
361
- - (Promise\<Object\>) - Cache object with name and metadata
362
-
363
- **Example:**
364
-
365
- ```javascript
366
- const cache = await gemini.cacheAdd({
367
- gsPath: 'gs://my-bucket/documentation.pdf',
368
- systemPrompt: 'You are a helpful documentation assistant.',
369
- cacheName: 'docs-cache',
370
- cacheTTL: '3600s',
371
- });
372
- ```
373
-
374
- ##### `client.cacheList()`
375
-
376
- Lists all available caches in the project.
377
-
378
- **Parameters:** None
379
-
380
- **Returns:**
381
-
382
- - (Promise\<Array\>) - Array of cache objects with `name` and `displayName` properties
383
-
384
- **Example:**
385
-
386
- ```javascript
387
- const caches = await gemini.cacheList();
388
- console.log(caches);
389
- // [{ name: 'projects/.../cachedContents/...', displayName: 'docs-cache' }]
390
- ```
391
-
392
- ##### `client.cacheUpdate(cacheName, cacheOptions)`
393
-
394
- Updates an existing cache configuration.
395
-
396
- **Parameters:**
397
-
398
- - `cacheName` (string) **required** - The cache name to update
399
- - `cacheOptions` (Object) **required** - Update configuration
400
- - `ttl` (string) - New time-to-live value (e.g., '7200s')
401
-
402
- **Returns:**
403
-
404
- - (Promise\<Object\>) - Updated cache object
405
-
406
- **Example:**
407
-
408
- ```javascript
409
- await gemini.cacheUpdate('projects/.../cachedContents/abc123', {
410
- ttl: '7200s', // Extend to 2 hours
411
- });
412
- ```
413
-
414
- ---
415
-
416
- ### `OpenAIAPI(options)`
417
-
418
- Creates a new OpenAI client instance supporting OpenAI and compatible APIs.
419
-
420
- #### Parameters
421
-
422
- - `options` (Object) - Configuration options
423
- - `apiKey` (string) **required** - Your OpenAI API key or compatible service key
424
- - `baseURL` (string) **required** - API base URL (e.g., 'https://api.openai.com/v1')
425
-
426
- #### Returns
427
-
428
- Returns an OpenAI client object with the following methods:
429
-
430
- ##### `client.chat(chatOptions)`
431
-
432
- Sends a chat request to the OpenAI API.
433
-
434
- **Parameters:**
435
-
436
- - `chatOptions` (Object) **required** - Native OpenAI API chat completion options
437
- - `model` (string) **required** - Model identifier (e.g., 'gpt-4o', 'deepseek-reasoner')
438
- - `messages` (Array) **required** - Array of message objects
439
- - `role` (string) - 'system', 'user', or 'assistant'
440
- - `content` (string) - Message content
441
- - `thinking` (Object) - Optional thinking/reasoning configuration
442
- - `type` (string) - 'enabled' or 'disabled'
443
- - ...other OpenAI API parameters
444
-
445
- **Returns:**
446
-
447
- - (Promise\<Object\>) - Message object with `role` and `content` properties
448
-
449
- **Example:**
450
-
451
- ```javascript
452
- const response = await openai.chat({
453
- model: 'gpt-4o',
454
- messages: [
455
- { role: 'system', content: 'You are a helpful coding assistant.' },
456
- { role: 'user', content: 'Write a Python function to reverse a string' },
457
- ],
458
- });
459
- console.log(response.content);
460
- ```
461
-
462
- ##### `client.chatWithStreaming(chatOptions, callbackOptions)`
463
-
464
- Sends a chat request to the OpenAI API with streaming response and thinking support.
465
-
466
- **Parameters:**
467
-
468
- - `chatOptions` (Object) **required** - Native OpenAI API chat completion options
469
- - `model` (string) **required** - Model identifier (e.g., 'gpt-4o', 'deepseek-reasoner')
470
- - `messages` (Array) **required** - Array of message objects
471
- - `role` (string) - 'system', 'user', or 'assistant'
472
- - `content` (string) - Message content
473
- - `thinking` (Object) - Optional thinking/reasoning configuration
474
- - `type` (string) - 'enabled' or 'disabled'
475
- - ...other OpenAI API parameters (note: `stream` will be automatically set to `true`)
476
-
477
- - `callbackOptions` (Object) **required** - Callback functions for handling stream events
478
- - `beginCallback` (Function) - Called when the stream begins
479
- - `firstThinkingCallback` (Function) - Called when the first thinking chunk is received (for reasoning models)
480
- - `thinkingCallback` (Function) - Called for each thinking/reasoning chunk received
481
- - Parameters: `thinking` (string) - The thinking content chunk
482
- - `firstContentCallback` (Function) - Called when the first response content chunk is received
483
- - `contentCallback` (Function) - Called for each response content chunk received
484
- - Parameters: `content` (string) - The text chunk
485
- - `endCallback` (Function) - Called when the stream ends successfully
486
- - `errorCallback` (Function) - Called if an error occurs
487
- - Parameters: `error` (Error) - The error object
488
-
489
- **Returns:**
490
-
491
- - (Promise\<void\>) - Resolves when streaming completes
492
-
493
- **Example:**
494
-
495
- ```javascript
496
- await openai.chatWithStreaming(
497
- {
498
- model: 'deepseek-reasoner',
499
- messages: [
500
- { role: 'system', content: 'You are a math tutor.' },
501
- { role: 'user', content: 'Solve: What is 15% of 240?' },
502
- ],
503
- thinking: {
504
- type: 'enabled',
505
- },
506
- },
507
- {
508
- thinkingCallback: (thinking) => {
509
- console.log('Thinking:', thinking);
510
- },
511
- contentCallback: (chunk) => {
512
- process.stdout.write(chunk);
513
- },
514
- endCallback: () => {
515
- console.log('\nDone!');
516
- },
517
- },
518
- );
519
- ```
120
+ - `agentEndCallback` returns truthy to break the sequence
121
+ - `agentBreakCallback` (optional) is called before breaking
520
122
 
521
123
  ## License
522
124
 
@@ -525,11 +127,3 @@ MIT
525
127
  ## Author
526
128
 
527
129
  uikoo9 <uikoo9@qq.com>
528
-
529
- ## Related Projects
530
-
531
- - [viho](https://github.com/uikoo9/viho) - Main CLI tool for managing AI models
532
-
533
- ## Contributing
534
-
535
- Issues and pull requests are welcome on [GitHub](https://github.com/uikoo9/viho/issues).
package/index.js CHANGED
@@ -520,10 +520,12 @@ const OpenAIAPI = (options) => {
520
520
  * @returns
521
521
  */
522
522
  const callLLM = async (options) => {
523
- const response = await options.llm.chat({
523
+ const chatOptions = {
524
524
  model: options.modelName,
525
525
  messages: options.messages,
526
- });
526
+ };
527
+ if (options.thinking) chatOptions.thinking = options.thinking;
528
+ const response = await options.llm.chat(chatOptions);
527
529
  const fullContent = response.content || '';
528
530
 
529
531
  // r
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "viho-llm",
3
- "version": "1.0.6",
3
+ "version": "1.0.7",
4
4
  "description": "Utility library for working with multiple LLM providers (Google Gemini and OpenAI), providing common tools and helpers for AI interactions",
5
5
  "keywords": [
6
6
  "llm",
@@ -68,5 +68,5 @@
68
68
  }
69
69
  }
70
70
  },
71
- "gitHead": "1c8edc1b39d4b2617ec3b6c6ed555e3c8a27a91d"
71
+ "gitHead": "e19813c5650c9966fac687b8e3940a34a8481deb"
72
72
  }
@@ -4,10 +4,12 @@
4
4
  * @returns
5
5
  */
6
6
  export const callLLM = async (options) => {
7
- const response = await options.llm.chat({
7
+ const chatOptions = {
8
8
  model: options.modelName,
9
9
  messages: options.messages,
10
- });
10
+ };
11
+ if (options.thinking) chatOptions.thinking = options.thinking;
12
+ const response = await options.llm.chat(chatOptions);
11
13
  const fullContent = response.content || '';
12
14
 
13
15
  // r