genai-lite 0.11.0 → 0.13.0

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
@@ -6,6 +6,7 @@ A lightweight, portable Node.js/TypeScript library providing a unified interface
6
6
 
7
7
  - 🔌 **Unified API** - Single interface for multiple AI providers
8
8
  - 🏠 **Local & Cloud Models** - Run models locally with llama.cpp or use cloud APIs
9
+ - ⚡ **Text Streaming** - Async iterable token deltas for OpenAI, Anthropic, Gemini, Mistral, OpenRouter, and llama.cpp
9
10
  - 🖼️ **Image Generation** - First-class support for AI image generation (OpenAI, local diffusion)
10
11
  - 🔐 **Flexible API Key Management** - Bring your own key storage solution
11
12
  - 📦 **Zero Electron Dependencies** - Works in any Node.js environment
@@ -77,6 +78,33 @@ if (response.object === 'chat.completion') {
77
78
  }
78
79
  ```
79
80
 
81
+ ### Streaming Text
82
+
83
+ ```typescript
84
+ import { LLMService } from 'genai-lite';
85
+
86
+ const llmService = new LLMService(async () => 'not-needed');
87
+
88
+ for await (const event of llmService.streamMessage({
89
+ providerId: 'llamacpp',
90
+ modelId: 'llamacpp',
91
+ messages: [{ role: 'user', content: 'Say hello in five words.' }],
92
+ settings: { maxTokens: 32 }
93
+ })) {
94
+ if (event.type === 'content_delta') {
95
+ process.stdout.write(event.delta);
96
+ } else if (event.type === 'reasoning_delta') {
97
+ process.stderr.write(event.delta);
98
+ } else if (event.type === 'complete') {
99
+ console.log('\nTokens:', event.response.usage?.total_tokens);
100
+ } else if (event.type === 'error') {
101
+ console.error(event.error.error.message);
102
+ }
103
+ }
104
+ ```
105
+
106
+ Streaming is implemented for all text providers: `openai`, `anthropic`, `gemini`, `mistral`, `openrouter`, and `llamacpp`. The final `complete.response` event contains the same normalized response shape returned by `sendMessage()`.
107
+
80
108
  ### Image Generation
81
109
 
82
110
  ```typescript
@@ -134,7 +162,7 @@ Comprehensive documentation is available in the **[`genai-lite-docs`](./genai-li
134
162
  - **Google Gemini** - Gemini 3 (Pro, Flash preview), Gemini 2.5, Gemma 3 & 4 (free)
135
163
  - **Mistral** - Codestral, Devstral
136
164
  - **OpenRouter** - Unified gateway to 100+ models (unknown models assumed reasoning-capable)
137
- - **llama.cpp** - Run any GGUF model locally (no API keys required); local reasoning toggle for detected models
165
+ - **llama.cpp** - Run any GGUF model locally (no API keys required); streaming and local reasoning toggle for detected models
138
166
 
139
167
  ### Image Providers
140
168
  - **OpenAI Images** - gpt-image-1, dall-e-3, dall-e-2
package/dist/index.d.ts CHANGED
@@ -1,6 +1,6 @@
1
1
  export type { ApiKeyProvider, PresetMode } from "./types";
2
2
  export { LLMService } from "./llm/LLMService";
3
- export type { LLMServiceOptions, SendMessageOptions, CreateMessagesResult } from "./llm/LLMService";
3
+ export type { LLMServiceOptions, SendMessageOptions, StreamMessageOptions, CreateMessagesResult } from "./llm/LLMService";
4
4
  export { withRetry, DEFAULT_RETRY_POLICY } from "./shared/services/withRetry";
5
5
  export type { RetryPolicy, RetryVerdict, WithRetryOptions } from "./shared/services/withRetry";
6
6
  export type { ModelPreset } from "./types/presets";
@@ -1,6 +1,6 @@
1
1
  import type { ApiKeyProvider, PresetMode } from '../types';
2
2
  import type { Logger, LogLevel } from '../logging/types';
3
- import type { LLMChatRequest, LLMChatRequestWithPreset, LLMResponse, LLMFailureResponse, ProviderInfo, ModelInfo, ApiProviderId, LLMSettings, ModelContext, LLMMessage } from "./types";
3
+ import type { LLMChatRequest, LLMChatRequestWithPreset, LLMResponse, LLMFailureResponse, ProviderInfo, ModelInfo, ApiProviderId, LLMSettings, ModelContext, LLMMessage, LLMStreamEvent, LLMRequestCapabilityPreflight, LLMRequestCapabilityValidationResult, ModelCapabilitiesResult, StructuredOutputSupport } from "./types";
4
4
  import type { ModelPreset } from "../types/presets";
5
5
  import { type RetryPolicy } from "../shared/services/withRetry";
6
6
  export type { PresetMode };
@@ -43,6 +43,18 @@ export interface SendMessageOptions {
43
43
  /** Per-request retry cap (overrides the service-level retry.maxRetries) */
44
44
  maxRetries?: number;
45
45
  }
46
+ /**
47
+ * Per-call options for LLMService.streamMessage
48
+ */
49
+ export interface StreamMessageOptions {
50
+ /**
51
+ * Abort signal to cancel the request (client-side - the provider may still
52
+ * process and bill an already-dispatched request).
53
+ */
54
+ signal?: AbortSignal;
55
+ /** Per-request timeout in ms (overrides the service-level timeoutMs) */
56
+ timeoutMs?: number;
57
+ }
46
58
  /**
47
59
  * Result from createMessages method
48
60
  */
@@ -89,6 +101,31 @@ export declare class LLMService {
89
101
  * @returns Promise resolving to array of model information
90
102
  */
91
103
  getModels(providerId: ApiProviderId): Promise<ModelInfo[]>;
104
+ /**
105
+ * Gets static capability metadata for a provider/model pair without retrieving
106
+ * API keys, calling provider adapters, or performing network I/O.
107
+ *
108
+ * Unknown or unregistered models use the same fallback model resolution policy
109
+ * as sendMessage(), but their optional capabilities are reported as unknown.
110
+ */
111
+ getModelCapabilities(providerId: ApiProviderId, modelId: string): Promise<ModelCapabilitiesResult | LLMFailureResponse>;
112
+ /**
113
+ * Convenience wrapper for checking structured-output support.
114
+ *
115
+ * Returns `unknown` when genai-lite has no explicit capability metadata. Callers
116
+ * should decide whether unknown is acceptable for their use case.
117
+ */
118
+ supportsStructuredOutput(providerId: ApiProviderId, modelId: string): Promise<StructuredOutputSupport | LLMFailureResponse>;
119
+ /**
120
+ * Preflights provider/model capability requirements for a request without
121
+ * retrieving API keys, calling provider adapters, or performing network I/O.
122
+ *
123
+ * This checks the effective settings after preset and model defaults are
124
+ * applied. Unknown/unspecified capabilities are reported as unknown and remain
125
+ * valid; explicitly unsupported capabilities return the same validation error
126
+ * shape as sendMessage() where possible.
127
+ */
128
+ validateRequestCapabilities(request: LLMRequestCapabilityPreflight): Promise<LLMRequestCapabilityValidationResult>;
92
129
  /**
93
130
  * Sends a chat message to an LLM provider
94
131
  *
@@ -96,6 +133,20 @@ export declare class LLMService {
96
133
  * @returns Promise resolving to either success or failure response
97
134
  */
98
135
  sendMessage(request: LLMChatRequest | LLMChatRequestWithPreset, callOptions?: SendMessageOptions): Promise<LLMResponse | LLMFailureResponse>;
136
+ /**
137
+ * Streams a chat message from an LLM provider.
138
+ *
139
+ * The final `complete` event contains the same normalized response shape as
140
+ * sendMessage(). Validation/API key failures and unsupported streaming adapters
141
+ * are yielded as a single `error` event.
142
+ */
143
+ streamMessage(request: LLMChatRequest | LLMChatRequestWithPreset, callOptions?: StreamMessageOptions): AsyncGenerator<LLMStreamEvent>;
144
+ private resolveAndValidateCapabilities;
145
+ private buildModelCapabilities;
146
+ private getStructuredOutputSupport;
147
+ private getCapabilitySource;
148
+ private prepareRequest;
149
+ private postProcessResponse;
99
150
  /**
100
151
  * Gets all configured model presets
101
152
  *