@sparkleideas/providers 3.5.2-patch.1

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/src/types.ts ADDED
@@ -0,0 +1,435 @@
1
+ /**
2
+ * V3 LLM Provider Types
3
+ *
4
+ * Unified type system for all LLM providers with enhanced
5
+ * cost tracking, model capabilities, and error handling.
6
+ *
7
+ * @module @sparkleideas/providers/types
8
+ */
9
+
10
+ import { EventEmitter } from 'events';
11
+
12
+ // ===== PROVIDER TYPES =====
13
+
14
+ export type LLMProvider =
15
+ | 'anthropic'
16
+ | 'openai'
17
+ | 'google'
18
+ | 'cohere'
19
+ | 'ollama'
20
+ | 'ruvector'
21
+ | 'openrouter'
22
+ | 'litellm'
23
+ | 'custom';
24
+
25
+ export type LLMModel =
26
+ // Anthropic Models (2024-2025)
27
+ | 'claude-3-5-sonnet-20241022'
28
+ | 'claude-3-5-sonnet-latest'
29
+ | 'claude-3-opus-20240229'
30
+ | 'claude-3-sonnet-20240229'
31
+ | 'claude-3-haiku-20240307'
32
+ // OpenAI Models (2024-2025)
33
+ | 'gpt-4o'
34
+ | 'gpt-4o-mini'
35
+ | 'gpt-4-turbo'
36
+ | 'gpt-4'
37
+ | 'gpt-3.5-turbo'
38
+ | 'o1-preview'
39
+ | 'o1-mini'
40
+ | 'o3-mini'
41
+ // Google Models
42
+ | 'gemini-2.0-flash'
43
+ | 'gemini-1.5-pro'
44
+ | 'gemini-1.5-flash'
45
+ | 'gemini-pro'
46
+ // Cohere Models
47
+ | 'command-r-plus'
48
+ | 'command-r'
49
+ | 'command-light'
50
+ | 'command'
51
+ // Ollama (Local) Models
52
+ | 'llama3.2'
53
+ | 'llama3.1'
54
+ | 'mistral'
55
+ | 'mixtral'
56
+ | 'codellama'
57
+ | 'phi-4'
58
+ | 'deepseek-coder'
59
+ // Generic
60
+ | 'custom-model'
61
+ | string;
62
+
63
+ // ===== MESSAGE TYPES =====
64
+
65
+ export interface LLMMessage {
66
+ role: 'system' | 'user' | 'assistant' | 'tool';
67
+ content: string | LLMContentPart[];
68
+ name?: string;
69
+ toolCallId?: string;
70
+ toolCalls?: LLMToolCall[];
71
+ }
72
+
73
+ export interface LLMContentPart {
74
+ type: 'text' | 'image' | 'audio';
75
+ text?: string;
76
+ imageUrl?: string;
77
+ imageBase64?: string;
78
+ audioUrl?: string;
79
+ }
80
+
81
+ export interface LLMToolCall {
82
+ id: string;
83
+ type: 'function';
84
+ function: {
85
+ name: string;
86
+ arguments: string;
87
+ };
88
+ }
89
+
90
+ export interface LLMTool {
91
+ type: 'function';
92
+ function: {
93
+ name: string;
94
+ description: string;
95
+ parameters: {
96
+ type: 'object';
97
+ properties: Record<string, unknown>;
98
+ required?: string[];
99
+ };
100
+ };
101
+ }
102
+
103
+ // ===== REQUEST/RESPONSE =====
104
+
105
+ export interface LLMProviderConfig {
106
+ provider: LLMProvider;
107
+ apiKey?: string;
108
+ apiUrl?: string;
109
+ model: LLMModel;
110
+
111
+ // Generation parameters
112
+ temperature?: number;
113
+ maxTokens?: number;
114
+ topP?: number;
115
+ topK?: number;
116
+ frequencyPenalty?: number;
117
+ presencePenalty?: number;
118
+ stopSequences?: string[];
119
+
120
+ // Provider-specific options
121
+ providerOptions?: Record<string, unknown>;
122
+
123
+ // Performance settings
124
+ timeout?: number;
125
+ retryAttempts?: number;
126
+ retryDelay?: number;
127
+
128
+ // Features
129
+ enableStreaming?: boolean;
130
+ enableCaching?: boolean;
131
+ cacheTimeout?: number;
132
+
133
+ // Cost optimization
134
+ enableCostOptimization?: boolean;
135
+ maxCostPerRequest?: number;
136
+ fallbackModels?: LLMModel[];
137
+ }
138
+
139
+ export interface LLMRequest {
140
+ messages: LLMMessage[];
141
+ model?: LLMModel;
142
+ temperature?: number;
143
+ maxTokens?: number;
144
+ topP?: number;
145
+ topK?: number;
146
+ frequencyPenalty?: number;
147
+ presencePenalty?: number;
148
+ stopSequences?: string[];
149
+ stream?: boolean;
150
+
151
+ // Tool calling
152
+ tools?: LLMTool[];
153
+ toolChoice?: 'auto' | 'none' | 'required' | { type: 'function'; function: { name: string } };
154
+
155
+ // Provider-specific options
156
+ providerOptions?: Record<string, unknown>;
157
+
158
+ // Cost constraints
159
+ costConstraints?: {
160
+ maxCost?: number;
161
+ preferredModels?: LLMModel[];
162
+ };
163
+
164
+ // Request metadata
165
+ requestId?: string;
166
+ metadata?: Record<string, unknown>;
167
+ }
168
+
169
+ export interface LLMResponse {
170
+ id: string;
171
+ model: LLMModel;
172
+ provider: LLMProvider;
173
+
174
+ // Content
175
+ content: string;
176
+ toolCalls?: LLMToolCall[];
177
+
178
+ // Usage
179
+ usage: {
180
+ promptTokens: number;
181
+ completionTokens: number;
182
+ totalTokens: number;
183
+ };
184
+
185
+ // Cost tracking
186
+ cost?: {
187
+ promptCost: number;
188
+ completionCost: number;
189
+ totalCost: number;
190
+ currency: string;
191
+ };
192
+
193
+ // Performance
194
+ latency?: number;
195
+
196
+ // Metadata
197
+ finishReason?: 'stop' | 'length' | 'tool_calls' | 'content_filter';
198
+ metadata?: Record<string, unknown>;
199
+ }
200
+
201
+ export interface LLMStreamEvent {
202
+ type: 'content' | 'tool_call' | 'error' | 'done';
203
+ delta?: {
204
+ content?: string;
205
+ toolCall?: Partial<LLMToolCall>;
206
+ };
207
+ error?: Error;
208
+ usage?: LLMResponse['usage'];
209
+ cost?: LLMResponse['cost'];
210
+ }
211
+
212
+ // ===== PROVIDER CAPABILITIES =====
213
+
214
+ export interface ProviderCapabilities {
215
+ supportedModels: LLMModel[];
216
+ maxContextLength: Record<string, number>;
217
+ maxOutputTokens: Record<string, number>;
218
+
219
+ // Feature support
220
+ supportsStreaming: boolean;
221
+ supportsToolCalling: boolean;
222
+ supportsSystemMessages: boolean;
223
+ supportsVision: boolean;
224
+ supportsAudio: boolean;
225
+
226
+ // Advanced features
227
+ supportsFineTuning: boolean;
228
+ supportsEmbeddings: boolean;
229
+ supportsBatching: boolean;
230
+
231
+ // Rate limits
232
+ rateLimit?: {
233
+ requestsPerMinute: number;
234
+ tokensPerMinute: number;
235
+ concurrentRequests: number;
236
+ };
237
+
238
+ // Pricing (per 1K tokens)
239
+ pricing: Record<string, {
240
+ promptCostPer1k: number;
241
+ completionCostPer1k: number;
242
+ currency: string;
243
+ }>;
244
+ }
245
+
246
+ // ===== ERROR TYPES =====
247
+
248
+ export class LLMProviderError extends Error {
249
+ constructor(
250
+ message: string,
251
+ public code: string,
252
+ public provider: LLMProvider,
253
+ public statusCode?: number,
254
+ public retryable: boolean = true,
255
+ public details?: unknown
256
+ ) {
257
+ super(message);
258
+ this.name = 'LLMProviderError';
259
+ }
260
+ }
261
+
262
+ export class RateLimitError extends LLMProviderError {
263
+ constructor(
264
+ message: string,
265
+ provider: LLMProvider,
266
+ public retryAfter?: number,
267
+ details?: unknown
268
+ ) {
269
+ super(message, 'RATE_LIMIT', provider, 429, true, details);
270
+ this.name = 'RateLimitError';
271
+ }
272
+ }
273
+
274
+ export class AuthenticationError extends LLMProviderError {
275
+ constructor(message: string, provider: LLMProvider, details?: unknown) {
276
+ super(message, 'AUTHENTICATION', provider, 401, false, details);
277
+ this.name = 'AuthenticationError';
278
+ }
279
+ }
280
+
281
+ export class ModelNotFoundError extends LLMProviderError {
282
+ constructor(model: string, provider: LLMProvider, details?: unknown) {
283
+ super(`Model ${model} not found`, 'MODEL_NOT_FOUND', provider, 404, false, details);
284
+ this.name = 'ModelNotFoundError';
285
+ }
286
+ }
287
+
288
+ export class ProviderUnavailableError extends LLMProviderError {
289
+ constructor(provider: LLMProvider, details?: unknown) {
290
+ super(`Provider ${provider} is unavailable`, 'PROVIDER_UNAVAILABLE', provider, 503, true, details);
291
+ this.name = 'ProviderUnavailableError';
292
+ }
293
+ }
294
+
295
+ // ===== PROVIDER INTERFACE =====
296
+
297
+ export interface ILLMProvider extends EventEmitter {
298
+ readonly name: LLMProvider;
299
+ readonly capabilities: ProviderCapabilities;
300
+ config: LLMProviderConfig;
301
+
302
+ // Core methods
303
+ initialize(): Promise<void>;
304
+ complete(request: LLMRequest): Promise<LLMResponse>;
305
+ streamComplete(request: LLMRequest): AsyncIterable<LLMStreamEvent>;
306
+
307
+ // Model management
308
+ listModels(): Promise<LLMModel[]>;
309
+ getModelInfo(model: LLMModel): Promise<ModelInfo>;
310
+ validateModel(model: LLMModel): boolean;
311
+
312
+ // Health and status
313
+ healthCheck(): Promise<HealthCheckResult>;
314
+ getStatus(): ProviderStatus;
315
+
316
+ // Cost management
317
+ estimateCost(request: LLMRequest): Promise<CostEstimate>;
318
+ getUsage(period?: UsagePeriod): Promise<UsageStats>;
319
+
320
+ // Cleanup
321
+ destroy(): void;
322
+ }
323
+
324
+ export interface ModelInfo {
325
+ model: LLMModel;
326
+ name: string;
327
+ description: string;
328
+ contextLength: number;
329
+ maxOutputTokens: number;
330
+ supportedFeatures: string[];
331
+ pricing?: {
332
+ promptCostPer1k: number;
333
+ completionCostPer1k: number;
334
+ currency: string;
335
+ };
336
+ deprecated?: boolean;
337
+ recommendedReplacement?: LLMModel;
338
+ }
339
+
340
+ export interface HealthCheckResult {
341
+ healthy: boolean;
342
+ latency?: number;
343
+ error?: string;
344
+ timestamp: Date;
345
+ details?: Record<string, unknown>;
346
+ }
347
+
348
+ export interface ProviderStatus {
349
+ available: boolean;
350
+ currentLoad: number;
351
+ queueLength: number;
352
+ activeRequests: number;
353
+ rateLimitRemaining?: number;
354
+ rateLimitReset?: Date;
355
+ }
356
+
357
+ export interface CostEstimate {
358
+ estimatedPromptTokens: number;
359
+ estimatedCompletionTokens: number;
360
+ estimatedTotalTokens: number;
361
+ estimatedCost: {
362
+ prompt: number;
363
+ completion: number;
364
+ total: number;
365
+ currency: string;
366
+ };
367
+ confidence: number;
368
+ }
369
+
370
+ export interface UsageStats {
371
+ period: { start: Date; end: Date };
372
+ requests: number;
373
+ tokens: { prompt: number; completion: number; total: number };
374
+ cost: { prompt: number; completion: number; total: number; currency: string };
375
+ errors: number;
376
+ averageLatency: number;
377
+ modelBreakdown: Record<string, { requests: number; tokens: number; cost: number }>;
378
+ }
379
+
380
+ export type UsagePeriod = 'hour' | 'day' | 'week' | 'month' | 'all';
381
+
382
+ // ===== MANAGER TYPES =====
383
+
384
+ export type LoadBalancingStrategy = 'round-robin' | 'least-loaded' | 'latency-based' | 'cost-based';
385
+
386
+ export interface ProviderManagerConfig {
387
+ providers: LLMProviderConfig[];
388
+ defaultProvider?: LLMProvider;
389
+ loadBalancing?: {
390
+ enabled: boolean;
391
+ strategy: LoadBalancingStrategy;
392
+ };
393
+ fallback?: {
394
+ enabled: boolean;
395
+ maxAttempts: number;
396
+ };
397
+ cache?: {
398
+ enabled: boolean;
399
+ ttl: number;
400
+ maxSize: number;
401
+ };
402
+ costOptimization?: {
403
+ enabled: boolean;
404
+ maxCostPerRequest?: number;
405
+ };
406
+ }
407
+
408
+ // ===== TYPE GUARDS =====
409
+
410
+ export function isLLMResponse(obj: unknown): obj is LLMResponse {
411
+ return (
412
+ typeof obj === 'object' &&
413
+ obj !== null &&
414
+ 'id' in obj &&
415
+ 'content' in obj &&
416
+ 'provider' in obj
417
+ );
418
+ }
419
+
420
+ export function isLLMStreamEvent(obj: unknown): obj is LLMStreamEvent {
421
+ return (
422
+ typeof obj === 'object' &&
423
+ obj !== null &&
424
+ 'type' in obj &&
425
+ ['content', 'tool_call', 'error', 'done'].includes((obj as LLMStreamEvent).type)
426
+ );
427
+ }
428
+
429
+ export function isLLMProviderError(error: unknown): error is LLMProviderError {
430
+ return error instanceof LLMProviderError;
431
+ }
432
+
433
+ export function isRateLimitError(error: unknown): error is RateLimitError {
434
+ return error instanceof RateLimitError;
435
+ }