@tchavi/sdk 0.1.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.
@@ -0,0 +1,635 @@
1
+ /** Standard error response from the Tchavi API */
2
+ interface TchaviErrorResponse {
3
+ error: string;
4
+ message: string;
5
+ statusCode: number;
6
+ details?: unknown;
7
+ }
8
+ /** Paginated list response wrapper */
9
+ interface PaginatedResponse<T> {
10
+ data: T[];
11
+ page: number;
12
+ limit: number;
13
+ total: number;
14
+ hasMore: boolean;
15
+ }
16
+ /** Client constructor options */
17
+ interface TchaviClientOptions {
18
+ /** API key for proxy auth: `sk-tch-...` */
19
+ apiKey?: string;
20
+ /** Email for dashboard JWT auth (requires password) */
21
+ email?: string;
22
+ /** Password for dashboard JWT auth (requires email) */
23
+ password?: string;
24
+ /** Base URL override. Default: http://localhost:3001 */
25
+ baseURL?: string;
26
+ /** Max retry attempts on 429/502/503. Default: 2 */
27
+ maxRetries?: number;
28
+ /** Request timeout in ms. Default: 60000 */
29
+ timeout?: number;
30
+ }
31
+ /** Tchavi metadata appended to every proxy response */
32
+ interface TchaviMeta {
33
+ tier: string;
34
+ model_type: 'chat' | 'embedding' | 'image';
35
+ mode: string;
36
+ mode_effective: string;
37
+ credits_used: number;
38
+ credits_remaining: number;
39
+ }
40
+
41
+ type AuthMode = 'api-key' | 'jwt';
42
+ /**
43
+ * AuthStrategy holds and refreshes credentials.
44
+ * - API key mode: static header, no state
45
+ * - JWT mode: logs in lazily, stores the access token in memory,
46
+ * refreshes via /auth/refresh cookie when the token expires
47
+ */
48
+ declare class AuthStrategy {
49
+ private mode;
50
+ private apiKey?;
51
+ private accessToken?;
52
+ private tokenExpiresAt?;
53
+ private baseURL;
54
+ private email?;
55
+ private password?;
56
+ constructor(options: TchaviClientOptions);
57
+ /**
58
+ * Returns the Authorization header value for the current request.
59
+ * For JWT mode, lazily logs in and refreshes the token as needed.
60
+ */
61
+ getAuthHeader(): Promise<string>;
62
+ /** Store a token (e.g. after explicit login() call from AuthResource) */
63
+ setAccessToken(token: string, expiresInSeconds?: number): void;
64
+ getMode(): AuthMode;
65
+ private isTokenExpired;
66
+ private loginOrRefresh;
67
+ private tryRefresh;
68
+ private loginWithPassword;
69
+ }
70
+
71
+ interface RequestOptions {
72
+ method?: 'GET' | 'POST' | 'PUT' | 'PATCH' | 'DELETE';
73
+ path: string;
74
+ body?: unknown;
75
+ query?: Record<string, string | number | boolean | undefined>;
76
+ /** Skip auth header (used for public endpoints) */
77
+ skipAuth?: boolean;
78
+ /** Override timeout for this specific request */
79
+ timeout?: number;
80
+ }
81
+ /**
82
+ * Core HTTP client. All resource classes use this.
83
+ *
84
+ * Handles:
85
+ * - Auth header injection
86
+ * - Query string serialization
87
+ * - JSON body serialization
88
+ * - Non-2xx error mapping to typed error classes
89
+ * - Exponential backoff with jitter for retryable responses
90
+ * - AbortController-based timeouts
91
+ */
92
+ declare class HttpClient {
93
+ private baseURL;
94
+ private maxRetries;
95
+ private defaultTimeout;
96
+ private auth;
97
+ constructor(auth: AuthStrategy, baseURL: string, maxRetries: number, timeout: number);
98
+ request<T>(options: RequestOptions): Promise<T>;
99
+ /**
100
+ * Returns the raw Response — used for streaming so callers can pipe the body.
101
+ */
102
+ requestRaw(options: RequestOptions): Promise<Response>;
103
+ private buildURL;
104
+ /** Exponential backoff with full jitter */
105
+ private backoffMs;
106
+ private sleep;
107
+ }
108
+
109
+ /** A raw SSE event from the gateway */
110
+ interface SSEEvent {
111
+ event?: string;
112
+ data: string;
113
+ }
114
+ /** Final event emitted after [DONE] with credit metadata */
115
+ interface TchaviEvent {
116
+ type: 'tchavi';
117
+ data: TchaviMeta;
118
+ }
119
+ /** A parsed data chunk event */
120
+ interface DataEvent<T = unknown> {
121
+ type: 'data';
122
+ data: T;
123
+ }
124
+ /** Signal that the stream has ended */
125
+ interface DoneEvent {
126
+ type: 'done';
127
+ }
128
+ type StreamEvent<T> = DataEvent<T> | TchaviEvent | DoneEvent;
129
+
130
+ /**
131
+ * Wraps an SSE ReadableStream as an AsyncIterable<T>.
132
+ * Stores the final Tchavi metadata so it can be accessed after iteration.
133
+ *
134
+ * @example
135
+ * ```ts
136
+ * const stream = await client.chat.completions.create({ ..., stream: true });
137
+ * for await (const chunk of stream) {
138
+ * process.stdout.write(chunk.choices[0]?.delta?.content ?? '');
139
+ * }
140
+ * console.log('Credits used:', stream.finalMeta()?.credits_used);
141
+ * ```
142
+ */
143
+ declare class TchaviStream<T> implements AsyncIterable<T> {
144
+ private body;
145
+ private _tchaviMeta;
146
+ constructor(body: ReadableStream<Uint8Array>);
147
+ [Symbol.asyncIterator](): AsyncIterator<T>;
148
+ private _consume;
149
+ /** Returns Tchavi credit metadata once the stream is fully consumed. */
150
+ finalMeta(): TchaviMeta | null;
151
+ }
152
+
153
+ interface ChatMessage {
154
+ role: 'system' | 'user' | 'assistant' | 'tool';
155
+ content: string | null;
156
+ name?: string;
157
+ tool_calls?: ToolCall[];
158
+ tool_call_id?: string;
159
+ }
160
+ interface ToolCall {
161
+ id: string;
162
+ type: 'function';
163
+ function: {
164
+ name: string;
165
+ arguments: string;
166
+ };
167
+ }
168
+ interface Tool {
169
+ type: 'function';
170
+ function: {
171
+ name: string;
172
+ description?: string;
173
+ parameters?: Record<string, unknown>;
174
+ };
175
+ }
176
+ interface ChatCompletionCreateParamsBase {
177
+ model: string;
178
+ messages: ChatMessage[];
179
+ temperature?: number;
180
+ top_p?: number;
181
+ max_tokens?: number;
182
+ max_completion_tokens?: number;
183
+ n?: number;
184
+ stop?: string | string[];
185
+ presence_penalty?: number;
186
+ frequency_penalty?: number;
187
+ logit_bias?: Record<string, number>;
188
+ user?: string;
189
+ response_format?: {
190
+ type: 'text' | 'json_object' | 'json_schema';
191
+ json_schema?: unknown;
192
+ };
193
+ seed?: number;
194
+ tools?: Tool[];
195
+ tool_choice?: 'none' | 'auto' | 'required' | {
196
+ type: 'function';
197
+ function: {
198
+ name: string;
199
+ };
200
+ };
201
+ stream_options?: {
202
+ include_usage?: boolean;
203
+ };
204
+ }
205
+ interface ChatCompletionCreateParamsNonStreaming extends ChatCompletionCreateParamsBase {
206
+ stream?: false | null;
207
+ }
208
+ interface ChatCompletionCreateParamsStreaming extends ChatCompletionCreateParamsBase {
209
+ stream: true;
210
+ }
211
+ type ChatCompletionCreateParams = ChatCompletionCreateParamsNonStreaming | ChatCompletionCreateParamsStreaming;
212
+ interface ChatCompletionUsage {
213
+ prompt_tokens: number;
214
+ completion_tokens: number;
215
+ total_tokens: number;
216
+ }
217
+ interface ChatCompletionChoice {
218
+ index: number;
219
+ message: ChatMessage;
220
+ finish_reason: 'stop' | 'length' | 'tool_calls' | 'content_filter' | null;
221
+ logprobs?: unknown;
222
+ }
223
+ interface ChatCompletion {
224
+ id: string;
225
+ object: 'chat.completion';
226
+ created: number;
227
+ model: string;
228
+ choices: ChatCompletionChoice[];
229
+ usage?: ChatCompletionUsage;
230
+ system_fingerprint?: string;
231
+ tchavi: TchaviMeta;
232
+ }
233
+ interface ChatCompletionChunkChoice {
234
+ index: number;
235
+ delta: {
236
+ role?: 'assistant';
237
+ content?: string | null;
238
+ tool_calls?: Partial<ToolCall>[];
239
+ };
240
+ finish_reason: 'stop' | 'length' | 'tool_calls' | 'content_filter' | null;
241
+ }
242
+ interface ChatCompletionChunk {
243
+ id: string;
244
+ object: 'chat.completion.chunk';
245
+ created: number;
246
+ model: string;
247
+ choices: ChatCompletionChunkChoice[];
248
+ usage?: ChatCompletionUsage;
249
+ system_fingerprint?: string;
250
+ }
251
+
252
+ declare class Completions {
253
+ private http;
254
+ constructor(http: HttpClient);
255
+ create(params: ChatCompletionCreateParamsNonStreaming): Promise<ChatCompletion>;
256
+ create(params: ChatCompletionCreateParamsStreaming): Promise<TchaviStream<ChatCompletionChunk>>;
257
+ }
258
+
259
+ declare class Chat {
260
+ readonly completions: Completions;
261
+ constructor(http: HttpClient);
262
+ }
263
+
264
+ interface EmbeddingCreateParams {
265
+ model: string;
266
+ input: string | string[] | number[] | number[][];
267
+ encoding_format?: 'float' | 'base64';
268
+ dimensions?: number;
269
+ user?: string;
270
+ }
271
+ interface Embedding {
272
+ object: 'embedding';
273
+ index: number;
274
+ embedding: number[];
275
+ }
276
+ interface EmbeddingsResponse {
277
+ object: 'list';
278
+ data: Embedding[];
279
+ model: string;
280
+ usage: {
281
+ prompt_tokens: number;
282
+ total_tokens: number;
283
+ };
284
+ tchavi: TchaviMeta;
285
+ }
286
+
287
+ declare class Embeddings {
288
+ private http;
289
+ constructor(http: HttpClient);
290
+ create(params: EmbeddingCreateParams): Promise<EmbeddingsResponse>;
291
+ }
292
+
293
+ interface ImageGenerationParams {
294
+ prompt: string;
295
+ model?: string;
296
+ n?: number;
297
+ quality?: 'low' | 'medium' | 'high' | 'standard' | 'hd' | 'fast' | 'ultra';
298
+ response_format?: 'url' | 'b64_json';
299
+ size?: '256x256' | '512x512' | '1024x1024' | '1792x1024' | '1024x1792' | '1536x1024' | '1024x1536';
300
+ style?: 'vivid' | 'natural';
301
+ user?: string;
302
+ }
303
+ interface Image {
304
+ url?: string;
305
+ b64_json?: string;
306
+ revised_prompt?: string;
307
+ }
308
+ interface ImagesResponse {
309
+ created: number;
310
+ data: Image[];
311
+ tchavi: TchaviMeta;
312
+ }
313
+
314
+ declare class Generations {
315
+ private http;
316
+ constructor(http: HttpClient);
317
+ create(params: ImageGenerationParams): Promise<ImagesResponse>;
318
+ }
319
+
320
+ declare class Images {
321
+ readonly generations: Generations;
322
+ constructor(http: HttpClient);
323
+ }
324
+
325
+ type PackDuration = 'ONE_SHOT' | 'MONTHLY' | 'ANNUAL';
326
+ interface CreditBalance {
327
+ creditsBalance: number;
328
+ }
329
+ interface CreditPack {
330
+ id: string;
331
+ name: string;
332
+ credits: number;
333
+ price: number;
334
+ currency: string;
335
+ duration: PackDuration;
336
+ maxKeys: number;
337
+ rateLimit: number;
338
+ isActive: boolean;
339
+ description: string | null;
340
+ }
341
+
342
+ declare class Credits {
343
+ private http;
344
+ constructor(http: HttpClient);
345
+ getBalance(): Promise<CreditBalance>;
346
+ listPacks(): Promise<CreditPack[]>;
347
+ }
348
+
349
+ type KeyStatus = 'ACTIVE' | 'REVOKED' | 'EXPIRED' | 'SUSPENDED';
350
+ interface ApiKey {
351
+ id: string;
352
+ keyPrefix: string;
353
+ label: string | null;
354
+ status: KeyStatus;
355
+ allowedIps: string[] | null;
356
+ allowedEndpoints: string[] | null;
357
+ expiresAt: string | null;
358
+ lastUsedAt: string | null;
359
+ createdAt: string;
360
+ }
361
+ /** Returned only at creation — full key is shown once */
362
+ interface ApiKeyWithSecret extends ApiKey {
363
+ key: string;
364
+ }
365
+ interface CreateApiKeyParams {
366
+ label?: string;
367
+ allowedIps?: string[];
368
+ allowedEndpoints?: string[];
369
+ expiresAt?: string;
370
+ }
371
+ interface UpdateApiKeyParams {
372
+ label?: string;
373
+ allowedIps?: string[];
374
+ allowedEndpoints?: string[];
375
+ }
376
+
377
+ declare class ApiKeys {
378
+ private http;
379
+ constructor(http: HttpClient);
380
+ list(): Promise<ApiKey[]>;
381
+ create(params?: CreateApiKeyParams): Promise<ApiKeyWithSecret>;
382
+ retrieve(id: string): Promise<ApiKey>;
383
+ update(id: string, params: UpdateApiKeyParams): Promise<ApiKey>;
384
+ delete(id: string): Promise<{
385
+ message: string;
386
+ }>;
387
+ }
388
+
389
+ type UsagePeriod = 'day' | 'week' | 'month';
390
+ type LogStatus = 'SUCCESS' | 'ERROR' | 'RATE_LIMITED';
391
+ interface UsageStats {
392
+ totalRequests: number;
393
+ totalTokens: number;
394
+ totalCreditsUsed: number;
395
+ periodStart: string;
396
+ periodEnd: string;
397
+ }
398
+ interface UsageLog {
399
+ id: string;
400
+ apiKeyPrefix?: string;
401
+ endpoint: string;
402
+ model: string;
403
+ promptTokens: number;
404
+ completionTokens: number;
405
+ totalTokens: number;
406
+ creditsCharged: number;
407
+ latencyMs: number | null;
408
+ status: LogStatus;
409
+ errorCode: string | null;
410
+ createdAt: string;
411
+ }
412
+ interface GetStatsParams {
413
+ period?: UsagePeriod;
414
+ }
415
+ interface GetHistoryParams {
416
+ page?: number;
417
+ limit?: number;
418
+ model?: string;
419
+ endpoint?: string;
420
+ startDate?: string;
421
+ endDate?: string;
422
+ }
423
+
424
+ declare class Usage {
425
+ private http;
426
+ constructor(http: HttpClient);
427
+ getStats(params?: GetStatsParams): Promise<UsageStats>;
428
+ getHistory(params?: GetHistoryParams): Promise<PaginatedResponse<UsageLog>>;
429
+ }
430
+
431
+ type ModelTier = 'NANO' | 'STANDARD' | 'PRO' | 'PREMIUM';
432
+ type ModelType = 'chat' | 'embedding' | 'image';
433
+ interface ModelTierConfig {
434
+ id: string;
435
+ modelId: string;
436
+ tier: ModelTier;
437
+ creditsPerKInput: number;
438
+ creditsPerKOutput: number;
439
+ displayName: string;
440
+ provider: string;
441
+ supportsFlex: boolean;
442
+ isActive: boolean;
443
+ }
444
+
445
+ declare class Models {
446
+ private http;
447
+ constructor(http: HttpClient);
448
+ /** Lists all active model tiers. Pass `all: true` to include inactive ones (admin only). */
449
+ list(params?: {
450
+ all?: boolean;
451
+ }): Promise<ModelTierConfig[]>;
452
+ }
453
+
454
+ type PaymentStatus = 'PENDING' | 'COMPLETED' | 'FAILED' | 'REFUNDED';
455
+ type PaymentProvider = 'KKIAPAY' | 'PAWAPAY' | 'PAYSTACK' | 'STRIPE';
456
+ interface Payment {
457
+ id: string;
458
+ packId: string;
459
+ packName?: string;
460
+ amount: number;
461
+ currency: string;
462
+ provider: PaymentProvider;
463
+ status: PaymentStatus;
464
+ creditsGranted: number;
465
+ createdAt: string;
466
+ completedAt: string | null;
467
+ }
468
+ interface InitiatePaymentParams {
469
+ packId: string;
470
+ phone?: string;
471
+ correspondent?: string;
472
+ }
473
+ interface PaymentInitiateResponse {
474
+ paymentId: string;
475
+ status: PaymentStatus;
476
+ redirectUrl?: string;
477
+ depositId?: string;
478
+ }
479
+
480
+ declare class Payments {
481
+ private http;
482
+ constructor(http: HttpClient);
483
+ initiate(params: InitiatePaymentParams): Promise<PaymentInitiateResponse>;
484
+ getStatus(id: string): Promise<Payment>;
485
+ getHistory(params?: {
486
+ page?: number;
487
+ limit?: number;
488
+ }): Promise<PaginatedResponse<Payment>>;
489
+ }
490
+
491
+ interface LoginParams {
492
+ email: string;
493
+ password: string;
494
+ }
495
+ interface RegisterParams {
496
+ email: string;
497
+ password: string;
498
+ name?: string;
499
+ }
500
+ interface LoginResponse {
501
+ accessToken: string;
502
+ user: User;
503
+ }
504
+ interface User {
505
+ id: string;
506
+ email: string;
507
+ name: string | null;
508
+ role: 'USER' | 'ADMIN';
509
+ status: 'ACTIVE' | 'SUSPENDED' | 'BANNED' | 'DELETED';
510
+ emailVerified: boolean;
511
+ creditsBalance: number;
512
+ createdAt: string;
513
+ }
514
+ interface UpdateUserParams {
515
+ name?: string;
516
+ email?: string;
517
+ language?: 'fr' | 'en';
518
+ currentPassword?: string;
519
+ newPassword?: string;
520
+ }
521
+
522
+ declare class AuthResource {
523
+ private http;
524
+ private authStrategy;
525
+ constructor(http: HttpClient, authStrategy: AuthStrategy);
526
+ login(email: string, password: string): Promise<LoginResponse>;
527
+ register(params: RegisterParams): Promise<{
528
+ message: string;
529
+ user: User;
530
+ }>;
531
+ logout(): Promise<{
532
+ message: string;
533
+ }>;
534
+ }
535
+
536
+ declare class Users {
537
+ private http;
538
+ constructor(http: HttpClient);
539
+ me(): Promise<User>;
540
+ update(params: UpdateUserParams): Promise<User>;
541
+ }
542
+
543
+ /**
544
+ * Main Tchavi client. Mirrors the OpenAI SDK's resource-based API.
545
+ *
546
+ * @example API key mode (proxy endpoints):
547
+ * ```ts
548
+ * import Tchavi from '@tchavi/sdk';
549
+ *
550
+ * const client = new Tchavi({ apiKey: 'sk-tch-...' });
551
+ *
552
+ * const completion = await client.chat.completions.create({
553
+ * model: 'gpt-4o-mini',
554
+ * messages: [{ role: 'user', content: 'Hello' }],
555
+ * });
556
+ * console.log(completion.choices[0].message.content);
557
+ * console.log(completion.tchavi.credits_used);
558
+ * ```
559
+ *
560
+ * @example JWT mode (account management):
561
+ * ```ts
562
+ * const client = new Tchavi({ email: 'me@example.com', password: 'S3cret!' });
563
+ * const balance = await client.credits.getBalance();
564
+ * const keys = await client.apiKeys.list();
565
+ * ```
566
+ *
567
+ * @example Streaming:
568
+ * ```ts
569
+ * const stream = await client.chat.completions.create({
570
+ * model: 'gpt-4o',
571
+ * messages: [{ role: 'user', content: 'Tell me a story' }],
572
+ * stream: true,
573
+ * });
574
+ * for await (const chunk of stream) {
575
+ * process.stdout.write(chunk.choices[0]?.delta?.content ?? '');
576
+ * }
577
+ * console.log('\nCredits used:', stream.finalMeta()?.credits_used);
578
+ * ```
579
+ */
580
+ declare class Tchavi {
581
+ readonly chat: Chat;
582
+ readonly embeddings: Embeddings;
583
+ readonly images: Images;
584
+ readonly credits: Credits;
585
+ readonly apiKeys: ApiKeys;
586
+ readonly usage: Usage;
587
+ readonly models: Models;
588
+ readonly payments: Payments;
589
+ readonly auth: AuthResource;
590
+ readonly users: Users;
591
+ constructor(options: TchaviClientOptions);
592
+ }
593
+
594
+ /**
595
+ * Base error for all Tchavi SDK errors.
596
+ * Catches both network-level and API-level failures.
597
+ */
598
+ declare class TchaviError extends Error {
599
+ constructor(message: string);
600
+ }
601
+
602
+ /**
603
+ * An error returned by the Tchavi API as a JSON response.
604
+ * Maps directly to the server's { error, message, statusCode } shape.
605
+ */
606
+ declare class TchaviAPIError extends TchaviError {
607
+ readonly statusCode: number;
608
+ readonly errorCode: string;
609
+ readonly details?: unknown;
610
+ readonly headers: Record<string, string>;
611
+ constructor(response: TchaviErrorResponse, headers?: Record<string, string>);
612
+ /**
613
+ * Factory: inspect the raw response and construct the most specific subclass.
614
+ */
615
+ static fromResponse(response: TchaviErrorResponse, headers: Record<string, string>): TchaviAPIError;
616
+ }
617
+
618
+ /** Thrown when the gateway returns 401 (invalid/missing API key or JWT) */
619
+ declare class TchaviAuthenticationError extends TchaviAPIError {
620
+ constructor(response: TchaviErrorResponse, headers?: Record<string, string>);
621
+ }
622
+
623
+ /** Thrown on 429. `retryAfter` is in seconds if provided by the server. */
624
+ declare class TchaviRateLimitError extends TchaviAPIError {
625
+ readonly retryAfter: number | null;
626
+ constructor(response: TchaviErrorResponse, headers?: Record<string, string>);
627
+ }
628
+
629
+ /** Thrown on 402. `creditsRemaining` reflects your current balance. */
630
+ declare class TchaviInsufficientCreditsError extends TchaviAPIError {
631
+ readonly creditsRemaining: number;
632
+ constructor(response: TchaviErrorResponse, headers?: Record<string, string>);
633
+ }
634
+
635
+ export { type ApiKey, type ApiKeyWithSecret, type ChatCompletion, type ChatCompletionChoice, type ChatCompletionChunk, type ChatCompletionChunkChoice, type ChatCompletionCreateParams, type ChatCompletionCreateParamsNonStreaming, type ChatCompletionCreateParamsStreaming, type ChatCompletionUsage, type ChatMessage, type CreateApiKeyParams, type CreditBalance, type CreditPack, type DataEvent, type DoneEvent, type Embedding, type EmbeddingCreateParams, type EmbeddingsResponse, type GetHistoryParams, type GetStatsParams, type Image, type ImageGenerationParams, type ImagesResponse, type InitiatePaymentParams, type KeyStatus, type LogStatus, type LoginParams, type LoginResponse, type ModelTier, type ModelTierConfig, type ModelType, type PackDuration, type PaginatedResponse, type Payment, type PaymentInitiateResponse, type PaymentProvider, type PaymentStatus, type RegisterParams, type SSEEvent, type StreamEvent, Tchavi, TchaviAPIError, TchaviAuthenticationError, type TchaviClientOptions, TchaviError, type TchaviErrorResponse, type TchaviEvent, TchaviInsufficientCreditsError, type TchaviMeta, TchaviRateLimitError, TchaviStream, type Tool, type ToolCall, type UpdateApiKeyParams, type UpdateUserParams, type UsageLog, type UsagePeriod, type UsageStats, type User, Tchavi as default };