@routstr/sdk 0.3.7 → 0.3.9

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.
Files changed (39) hide show
  1. package/dist/client/index.d.mts +411 -0
  2. package/dist/client/index.d.ts +411 -0
  3. package/dist/client/index.js +4938 -0
  4. package/dist/client/index.js.map +1 -0
  5. package/dist/client/index.mjs +4932 -0
  6. package/dist/client/index.mjs.map +1 -0
  7. package/dist/discovery/index.d.mts +247 -0
  8. package/dist/discovery/index.d.ts +247 -0
  9. package/dist/discovery/index.js +894 -0
  10. package/dist/discovery/index.js.map +1 -0
  11. package/dist/discovery/index.mjs +891 -0
  12. package/dist/discovery/index.mjs.map +1 -0
  13. package/dist/index.d.mts +195 -0
  14. package/dist/index.d.ts +195 -0
  15. package/dist/index.js +6797 -0
  16. package/dist/index.js.map +1 -0
  17. package/dist/index.mjs +6746 -0
  18. package/dist/index.mjs.map +1 -0
  19. package/dist/interfaces-C-DYd9Jy.d.ts +176 -0
  20. package/dist/interfaces-Csn8Uq04.d.mts +176 -0
  21. package/dist/interfaces-Cv1k2EUK.d.mts +118 -0
  22. package/dist/interfaces-iL7CWeG5.d.ts +118 -0
  23. package/dist/storage/index.d.mts +113 -0
  24. package/dist/storage/index.d.ts +113 -0
  25. package/dist/storage/index.js +2019 -0
  26. package/dist/storage/index.js.map +1 -0
  27. package/dist/storage/index.mjs +1995 -0
  28. package/dist/storage/index.mjs.map +1 -0
  29. package/dist/store-58VcEUoA.d.ts +172 -0
  30. package/dist/store-C6dfj1cc.d.mts +172 -0
  31. package/dist/types-_21yYFZG.d.mts +234 -0
  32. package/dist/types-_21yYFZG.d.ts +234 -0
  33. package/dist/wallet/index.d.mts +249 -0
  34. package/dist/wallet/index.d.ts +249 -0
  35. package/dist/wallet/index.js +1383 -0
  36. package/dist/wallet/index.js.map +1 -0
  37. package/dist/wallet/index.mjs +1380 -0
  38. package/dist/wallet/index.mjs.map +1 -0
  39. package/package.json +3 -2
@@ -0,0 +1,411 @@
1
+ import { e as Model, S as SdkLogger, M as Message, n as TransactionHistory, m as StreamingResult } from '../types-_21yYFZG.mjs';
2
+ import { P as ProviderRegistry, W as WalletAdapter, S as StorageAdapter, a as StreamingCallbacks } from '../interfaces-Csn8Uq04.mjs';
3
+ import { S as SdkStore, U as UsageTrackingDriver } from '../store-C6dfj1cc.mjs';
4
+ import { CashuSpender, BalanceManager } from '../wallet/index.mjs';
5
+ import { Transform } from 'stream';
6
+ import 'zustand/vanilla';
7
+ import '../interfaces-Cv1k2EUK.mjs';
8
+
9
+ /**
10
+ * ProviderManager - Handles provider selection and failover logic
11
+ *
12
+ * Handles:
13
+ * - Finding the best provider for a model based on price
14
+ * - Provider failover when errors occur
15
+ * - Tracking failed providers to avoid retry loops
16
+ * - Provider version compatibility
17
+ *
18
+ * Extracted from utils/apiUtils.ts findNextBestProvider and related logic
19
+ */
20
+
21
+ interface ModelProviderPrice {
22
+ baseUrl: string;
23
+ model: Model;
24
+ promptPerMillion: number;
25
+ completionPerMillion: number;
26
+ totalPerMillion: number;
27
+ }
28
+ declare class ProviderManager {
29
+ private providerRegistry;
30
+ private failedProviders;
31
+ /** Track when each provider last failed (provider URL -> timestamp) */
32
+ private lastFailed;
33
+ /** Providers on cooldown: [provider_url, cooldown_started_timestamp][] */
34
+ private providersOnCoolDown;
35
+ /** Cooldown duration in milliseconds (42 seconds) */
36
+ private static readonly COOLDOWN_DURATION_MS;
37
+ /** Optional persistent store for failure tracking */
38
+ private store;
39
+ /** Instance ID for debugging */
40
+ private readonly instanceId;
41
+ private readonly logger;
42
+ constructor(providerRegistry: ProviderRegistry, store?: SdkStore, logger?: SdkLogger);
43
+ /**
44
+ * Hydrate in-memory state from persistent store
45
+ */
46
+ private hydrateFromStore;
47
+ /**
48
+ * Get instance ID for debugging
49
+ */
50
+ getInstanceId(): string;
51
+ /**
52
+ * Clean up expired cooldown entries
53
+ * Also removes the provider from failedProviders so it can be retried
54
+ */
55
+ private cleanupExpiredCooldowns;
56
+ /**
57
+ * Get the cooldown duration in milliseconds
58
+ */
59
+ getCooldownDurationMs(): number;
60
+ /**
61
+ * Check if a provider is currently on cooldown
62
+ */
63
+ isOnCooldown(baseUrl: string): boolean;
64
+ /**
65
+ * Get all providers currently on cooldown
66
+ */
67
+ getProvidersOnCooldown(): [string, number][];
68
+ /**
69
+ * Reset the failed providers list
70
+ */
71
+ resetFailedProviders(): void;
72
+ /**
73
+ * Get the last failed timestamp for a provider
74
+ */
75
+ getLastFailed(baseUrl: string): number | undefined;
76
+ /**
77
+ * Get all providers with their last failed timestamps
78
+ */
79
+ getAllLastFailed(): Map<string, number>;
80
+ /**
81
+ * Mark a provider as failed
82
+ * If a provider fails twice within 5 minutes, it's added to cooldown
83
+ */
84
+ markFailed(baseUrl: string): void;
85
+ /**
86
+ * Remove a provider from cooldown (e.g., after successful request)
87
+ */
88
+ removeFromCooldown(baseUrl: string): void;
89
+ /**
90
+ * Clear all cooldown tracking
91
+ */
92
+ clearCooldowns(): void;
93
+ /**
94
+ * Clear all failure tracking (lastFailed timestamps)
95
+ */
96
+ clearFailureHistory(): void;
97
+ /**
98
+ * Check if a provider has failed
99
+ */
100
+ hasFailed(baseUrl: string): boolean;
101
+ /**
102
+ * Get a copy of the failed providers set
103
+ */
104
+ getFailedProviders(): Set<string>;
105
+ /**
106
+ * Find the next best provider for a model
107
+ * @param modelId The model ID to find a provider for
108
+ * @param currentBaseUrl The current provider to exclude
109
+ * @returns The best provider URL or null if none available
110
+ */
111
+ findNextBestProvider(modelId: string, currentBaseUrl: string): string | null;
112
+ /**
113
+ * Find the best model for a provider
114
+ * Useful when switching providers and need to find equivalent model
115
+ */
116
+ getModelForProvider(baseUrl: string, modelId: string): Promise<Model | null>;
117
+ /**
118
+ * Get all available providers for a model
119
+ * Returns sorted list by price
120
+ */
121
+ getAllProvidersForModel(modelId: string): Array<{
122
+ baseUrl: string;
123
+ model: Model;
124
+ cost: number;
125
+ }>;
126
+ /**
127
+ * Get providers for a model sorted by prompt+completion pricing
128
+ */
129
+ getProviderPriceRankingForModel(modelId: string, options?: {
130
+ torMode?: boolean;
131
+ includeDisabled?: boolean;
132
+ }): ModelProviderPrice[];
133
+ /**
134
+ * Get best-priced provider for a specific model
135
+ */
136
+ getBestProviderForModel(modelId: string, options?: {
137
+ torMode?: boolean;
138
+ includeDisabled?: boolean;
139
+ }): string | null;
140
+ private normalizeModelId;
141
+ /**
142
+ * Check if a provider accepts a specific mint
143
+ */
144
+ providerAcceptsMint(baseUrl: string, mintUrl: string): boolean;
145
+ /**
146
+ * Get required sats for a model based on message history
147
+ * Simple estimation based on typical usage
148
+ */
149
+ getRequiredSatsForModel(model: Model, apiMessages: any[], maxTokens?: number): number;
150
+ }
151
+
152
+ /**
153
+ * RoutstrClient - Main API client for Routstr
154
+ *
155
+ * Orchestrates:
156
+ * - Token spending via CashuSpender
157
+ * - API requests with authentication
158
+ * - Streaming response processing
159
+ * - Provider failover via ProviderManager
160
+ * - Error handling and refunds
161
+ *
162
+ * Extracted from utils/apiUtils.ts
163
+ */
164
+
165
+ /**
166
+ * Options for fetching AI response
167
+ */
168
+ interface FetchOptions {
169
+ messageHistory: Message[];
170
+ selectedModel: Model;
171
+ baseUrl: string;
172
+ mintUrl: string;
173
+ balance: number;
174
+ transactionHistory: TransactionHistory[];
175
+ maxTokens?: number;
176
+ headers?: Record<string, string>;
177
+ }
178
+ /**
179
+ * RoutstrClient is the main SDK entry point
180
+ */
181
+ type AlertLevel = "max" | "min";
182
+ type RoutstrClientMode = "xcashu" | "apikeys";
183
+ type DebugLevel = "DEBUG" | "WARN" | "ERROR";
184
+ interface RouteRequestParams {
185
+ path: string;
186
+ method: string;
187
+ body?: unknown;
188
+ headers?: Record<string, string>;
189
+ baseUrl: string;
190
+ mintUrl: string;
191
+ modelId?: string;
192
+ clientApiKey?: string;
193
+ }
194
+ interface RoutstrClientConfig {
195
+ usageTrackingDriver?: UsageTrackingDriver;
196
+ sdkStore?: SdkStore;
197
+ /** Optional: shared ProviderManager instance for consistent failure tracking across requests */
198
+ providerManager?: ProviderManager;
199
+ /** Optional: injectable logger (defaults to consoleLogger) */
200
+ logger?: SdkLogger;
201
+ }
202
+ declare class RoutstrClient {
203
+ private walletAdapter;
204
+ private storageAdapter;
205
+ private providerRegistry;
206
+ private cashuSpender;
207
+ private balanceManager;
208
+ private streamProcessor;
209
+ private providerManager;
210
+ private alertLevel;
211
+ private mode;
212
+ private debugLevel;
213
+ private usageTrackingDriver?;
214
+ private sdkStore?;
215
+ private logger;
216
+ constructor(walletAdapter: WalletAdapter, storageAdapter: StorageAdapter, providerRegistry: ProviderRegistry, alertLevel: AlertLevel, mode?: RoutstrClientMode, options?: RoutstrClientConfig);
217
+ /**
218
+ * Get the current client mode
219
+ */
220
+ getMode(): RoutstrClientMode;
221
+ getDebugLevel(): DebugLevel;
222
+ setDebugLevel(level: DebugLevel): void;
223
+ private _log;
224
+ /**
225
+ * Get the CashuSpender instance
226
+ */
227
+ getCashuSpender(): CashuSpender;
228
+ /**
229
+ * Get the BalanceManager instance
230
+ */
231
+ getBalanceManager(): BalanceManager;
232
+ /**
233
+ * Get the ProviderManager instance
234
+ */
235
+ getProviderManager(): ProviderManager;
236
+ /**
237
+ * Check if the client is currently busy (in critical section)
238
+ */
239
+ get isBusy(): boolean;
240
+ /**
241
+ * Route an API request to the upstream provider
242
+ *
243
+ * This is a simpler alternative to fetchAIResponse that just proxies
244
+ * the request upstream without the streaming callback machinery.
245
+ * Useful for daemon-style routing where you just need to forward
246
+ * requests and get responses back.
247
+ */
248
+ routeRequest(params: RouteRequestParams): Promise<Response>;
249
+ private _prepareRoutedRequest;
250
+ /**
251
+ * Extract clientApiKey from Authorization Bearer token if present
252
+ */
253
+ private _extractClientApiKey;
254
+ /**
255
+ * Fetch AI response with streaming
256
+ */
257
+ fetchAIResponse(options: FetchOptions, callbacks: StreamingCallbacks): Promise<void>;
258
+ /**
259
+ * Make the API request with failover support
260
+ */
261
+ private _makeRequest;
262
+ /**
263
+ * Handle error responses with failover
264
+ */
265
+ private _handleErrorResponse;
266
+ /**
267
+ * Handle post-response balance update for all modes
268
+ */
269
+ private _handlePostResponseBalanceUpdate;
270
+ private _trackResponseUsage;
271
+ /**
272
+ * Convert messages for API format
273
+ */
274
+ private _convertMessages;
275
+ /**
276
+ * Create assistant message from streaming result
277
+ */
278
+ private _createAssistantMessage;
279
+ /**
280
+ * Calculate estimated costs from usage
281
+ */
282
+ private _getEstimatedCosts;
283
+ /**
284
+ * Get pending API key amount
285
+ */
286
+ private _getPendingCashuTokenAmount;
287
+ /**
288
+ * Handle errors and notify callbacks
289
+ */
290
+ private _handleError;
291
+ /**
292
+ * Check wallet balance and throw if insufficient
293
+ */
294
+ private _checkBalance;
295
+ /**
296
+ * Spend a token using CashuSpender with standardized error handling
297
+ */
298
+ private _spendToken;
299
+ /**
300
+ * Build request headers with common defaults and dev mock controls
301
+ */
302
+ private _buildBaseHeaders;
303
+ /**
304
+ * Attach auth headers using the active client mode
305
+ */
306
+ private _withAuthHeader;
307
+ }
308
+
309
+ /**
310
+ * StreamProcessor - Handles SSE streaming response parsing
311
+ *
312
+ * Handles:
313
+ * - Line buffering for large payloads
314
+ * - Content extraction from delta chunks
315
+ * - Thinking/reasoning block extraction
316
+ * - Image data merging and deduplication
317
+ * - Usage statistics extraction
318
+ * - Citations and annotations
319
+ *
320
+ * Extracted from utils/apiUtils.ts processStreamingResponse
321
+ */
322
+
323
+ /**
324
+ * Callbacks for streaming updates
325
+ */
326
+ interface StreamCallbacks {
327
+ /** Called when new content arrives */
328
+ onContent: (content: string) => void;
329
+ /** Called when thinking content arrives */
330
+ onThinking: (thinking: string) => void;
331
+ }
332
+ /**
333
+ * StreamProcessor parses SSE streaming responses
334
+ */
335
+ declare class StreamProcessor {
336
+ private accumulatedContent;
337
+ private accumulatedThinking;
338
+ private accumulatedImages;
339
+ private isInThinking;
340
+ private isInContent;
341
+ /**
342
+ * Process a streaming response
343
+ */
344
+ process(response: Response, callbacks: StreamCallbacks, modelId?: string): Promise<StreamingResult>;
345
+ /**
346
+ * Parse a single SSE line
347
+ */
348
+ private _parseLine;
349
+ /**
350
+ * Handle content delta with thinking support
351
+ */
352
+ private _handleContent;
353
+ /**
354
+ * Handle thinking/reasoning content
355
+ */
356
+ private _handleThinking;
357
+ /**
358
+ * Extract thinking blocks from content (for models with inline thinking)
359
+ */
360
+ private _extractThinkingFromContent;
361
+ /**
362
+ * Merge images into accumulated array, avoiding duplicates
363
+ */
364
+ private _mergeImages;
365
+ }
366
+
367
+ interface UsageTrackingData {
368
+ promptTokens: number;
369
+ completionTokens: number;
370
+ totalTokens: number;
371
+ cost: number;
372
+ satsCost: number;
373
+ }
374
+
375
+ /**
376
+ * Inspect a Web `ReadableStream<Uint8Array>` of SSE bytes for `usage` and
377
+ * response `id` fields without touching the bytes that are delivered to the
378
+ * real client. This is meant to be called on one branch of a `body.tee()`.
379
+ *
380
+ * The inspector reads the stream to completion (or errors out), decoding
381
+ * UTF-8 across chunk boundaries, splitting on SSE event terminators
382
+ * (`\r?\n\r?\n`), parsing each `data:` payload as JSON, and invoking the
383
+ * provided callbacks when usage / response id become known.
384
+ *
385
+ * The returned Promise resolves with the final captured values once the
386
+ * stream ends (or is cancelled / errors out).
387
+ */
388
+ declare function inspectSSEWebStream(stream: ReadableStream<Uint8Array>, onUsage: (usage: UsageTrackingData) => void, onResponseId?: (responseId: string) => void): Promise<{
389
+ capturedUsage?: UsageTrackingData;
390
+ capturedResponseId?: string;
391
+ }>;
392
+ /**
393
+ * SSE parser transform that preserves the original byte stream.
394
+ *
395
+ * Incoming chunks are forwarded downstream unchanged so chunk boundaries and
396
+ * timing remain identical to the upstream source. In parallel, a streaming text
397
+ * decoder buffers just enough data to detect complete SSE event blocks for
398
+ * usage/responseId inspection.
399
+ *
400
+ * This means:
401
+ * - The client sees the original stream bytes without parser-induced
402
+ * re-chunking.
403
+ * - Multi-line events (multiple `data:` lines, plus `event:`/`id:`/`retry:`
404
+ * fields) are still parsed correctly for inspection.
405
+ * - Chunks that contain multiple events, or events split across chunks, are
406
+ * handled correctly without merging or losing packets.
407
+ * - UTF-8 split across chunk boundaries is decoded safely.
408
+ */
409
+ declare function createSSEParserTransform(onUsage: (usage: UsageTrackingData) => void, onResponseId?: (responseId: string) => void): Transform;
410
+
411
+ export { type AlertLevel, type DebugLevel, type FetchOptions, type ModelProviderPrice, ProviderManager, type RouteRequestParams, RoutstrClient, type RoutstrClientConfig, type RoutstrClientMode, type StreamCallbacks, StreamProcessor, createSSEParserTransform, inspectSSEWebStream };