@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.
package/README.md ADDED
@@ -0,0 +1,247 @@
1
+ # @tchavi/sdk
2
+
3
+ Official Node.js SDK for the [Tchavi](https://tchavi.io) AI API gateway — use OpenAI-compatible models with credit-based billing, without managing provider keys yourself.
4
+
5
+ [![npm version](https://img.shields.io/npm/v/@tchavi/sdk)](https://www.npmjs.com/package/@tchavi/sdk)
6
+ [![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](LICENSE)
7
+
8
+ ## Requirements
9
+
10
+ - Node.js **20+** (uses native `fetch` and `ReadableStream`)
11
+ - TypeScript **5+** (optional but recommended)
12
+
13
+ ## Installation
14
+
15
+ ```bash
16
+ npm install @tchavi/sdk
17
+ # or
18
+ pnpm add @tchavi/sdk
19
+ # or
20
+ yarn add @tchavi/sdk
21
+ ```
22
+
23
+ ## Quick start
24
+
25
+ ```ts
26
+ import Tchavi from '@tchavi/sdk';
27
+
28
+ const client = new Tchavi({ apiKey: 'sk-tch-...' });
29
+
30
+ const response = await client.chat.completions.create({
31
+ model: 'gpt-4o-mini',
32
+ messages: [{ role: 'user', content: 'Hello!' }],
33
+ });
34
+
35
+ console.log(response.choices[0].message.content);
36
+ console.log('Credits used:', response.tchavi.credits_used);
37
+ ```
38
+
39
+ Get your API key from the [Tchavi dashboard](https://app.tchavi.io).
40
+
41
+ ---
42
+
43
+ ## Chat completions
44
+
45
+ ### Non-streaming
46
+
47
+ ```ts
48
+ const completion = await client.chat.completions.create({
49
+ model: 'gpt-4o-mini',
50
+ messages: [
51
+ { role: 'system', content: 'You are a helpful assistant.' },
52
+ { role: 'user', content: 'What is the capital of France?' },
53
+ ],
54
+ temperature: 0.7,
55
+ max_tokens: 256,
56
+ });
57
+
58
+ console.log(completion.choices[0].message.content);
59
+ // Credit metadata appended by Tchavi:
60
+ console.log(completion.tchavi.credits_used);
61
+ console.log(completion.tchavi.credits_remaining);
62
+ ```
63
+
64
+ ### Streaming
65
+
66
+ ```ts
67
+ const stream = await client.chat.completions.create({
68
+ model: 'gpt-4o',
69
+ messages: [{ role: 'user', content: 'Tell me a story.' }],
70
+ stream: true,
71
+ });
72
+
73
+ for await (const chunk of stream) {
74
+ process.stdout.write(chunk.choices[0]?.delta?.content ?? '');
75
+ }
76
+
77
+ // Credit metadata available after iteration completes:
78
+ const meta = stream.finalMeta();
79
+ console.log('\nCredits used:', meta?.credits_used);
80
+ ```
81
+
82
+ ---
83
+
84
+ ## Embeddings
85
+
86
+ ```ts
87
+ const result = await client.embeddings.create({
88
+ model: 'text-embedding-3-small',
89
+ input: 'The quick brown fox jumps over the lazy dog',
90
+ });
91
+
92
+ console.log(result.data[0].embedding); // number[]
93
+ ```
94
+
95
+ ---
96
+
97
+ ## Image generation
98
+
99
+ ```ts
100
+ const result = await client.images.generations.create({
101
+ prompt: 'A futuristic city skyline at sunset',
102
+ model: 'dall-e-3',
103
+ n: 1,
104
+ size: '1024x1024',
105
+ });
106
+
107
+ console.log(result.data[0].url);
108
+ ```
109
+
110
+ ---
111
+
112
+ ## Error handling
113
+
114
+ ```ts
115
+ import Tchavi, {
116
+ TchaviAuthenticationError,
117
+ TchaviInsufficientCreditsError,
118
+ TchaviRateLimitError,
119
+ TchaviAPIError,
120
+ TchaviError,
121
+ } from '@tchavi/sdk';
122
+
123
+ try {
124
+ const response = await client.chat.completions.create({ ... });
125
+ } catch (err) {
126
+ if (err instanceof TchaviInsufficientCreditsError) {
127
+ // 402 — top up credits
128
+ console.log('Credits remaining:', err.creditsRemaining);
129
+ } else if (err instanceof TchaviRateLimitError) {
130
+ // 429 — back off and retry
131
+ console.log('Retry after (s):', err.retryAfter); // number | null
132
+ } else if (err instanceof TchaviAuthenticationError) {
133
+ // 401 — invalid or revoked API key
134
+ console.log('Check your API key');
135
+ } else if (err instanceof TchaviAPIError) {
136
+ // Other HTTP errors
137
+ console.log(err.statusCode, err.errorCode, err.message);
138
+ } else if (err instanceof TchaviError) {
139
+ // Network/timeout errors
140
+ console.log('Network error:', err.message);
141
+ }
142
+ }
143
+ ```
144
+
145
+ | Error class | Status | Extra fields |
146
+ |---|---|---|
147
+ | `TchaviError` | — | Base class for all SDK errors |
148
+ | `TchaviAPIError` | any | `statusCode`, `errorCode`, `headers` |
149
+ | `TchaviAuthenticationError` | 401 | — |
150
+ | `TchaviInsufficientCreditsError` | 402 | `creditsRemaining: number` |
151
+ | `TchaviRateLimitError` | 429 | `retryAfter: number \| null` |
152
+
153
+ ---
154
+
155
+ ## Account management
156
+
157
+ These methods use **JWT auth** — pass `email` and `password` instead of `apiKey`:
158
+
159
+ ```ts
160
+ const client = new Tchavi({
161
+ email: 'me@example.com',
162
+ password: 'my-password',
163
+ });
164
+ ```
165
+
166
+ ### Credits
167
+
168
+ ```ts
169
+ const { creditsBalance } = await client.credits.getBalance();
170
+ const packs = await client.credits.listPacks(); // available credit packs
171
+ ```
172
+
173
+ ### API keys
174
+
175
+ ```ts
176
+ // List all keys
177
+ const keys = await client.apiKeys.list();
178
+
179
+ // Create a new key (full secret shown only once)
180
+ const { plaintext, ...key } = await client.apiKeys.create({ name: 'Production' });
181
+ console.log('Save this:', plaintext);
182
+
183
+ // Retrieve / update / delete
184
+ const key = await client.apiKeys.retrieve('key-id');
185
+ await client.apiKeys.update('key-id', { name: 'Renamed', status: 'INACTIVE' });
186
+ await client.apiKeys.delete('key-id');
187
+ ```
188
+
189
+ ### Usage
190
+
191
+ ```ts
192
+ const stats = await client.usage.getStats({ period: '30d' });
193
+ const history = await client.usage.getHistory({ page: 1, limit: 20 });
194
+ ```
195
+
196
+ ### Payments
197
+
198
+ ```ts
199
+ // Initiate a credit purchase
200
+ const payment = await client.payments.initiate({ packId: 'pack-id', phone: '+22900000000' });
201
+
202
+ // Check payment status
203
+ const status = await client.payments.getStatus(payment.id);
204
+
205
+ // Payment history
206
+ const history = await client.payments.getHistory();
207
+ ```
208
+
209
+ ### Available models
210
+
211
+ ```ts
212
+ const models = await client.models.list();
213
+ // models[].id — use this as the `model` field in requests
214
+ ```
215
+
216
+ ---
217
+
218
+ ## Configuration
219
+
220
+ ```ts
221
+ const client = new Tchavi({
222
+ // Authentication (one of):
223
+ apiKey: 'sk-tch-...', // For proxy endpoints (chat, embeddings, images)
224
+ email: 'me@example.com', // For account management endpoints
225
+ password: 'my-password', // (requires email)
226
+
227
+ // Optional:
228
+ baseURL: 'https://tchavi.com', // Default: http://localhost:3001
229
+ maxRetries: 2, // Retries on 429/502/503. Default: 2
230
+ timeout: 60_000, // Request timeout in ms. Default: 60000
231
+ });
232
+ ```
233
+
234
+ | Option | Type | Default | Description |
235
+ |---|---|---|---|
236
+ | `apiKey` | `string` | — | API key (`sk-tch-...`) for proxy auth |
237
+ | `email` | `string` | — | Email for JWT auth |
238
+ | `password` | `string` | — | Password for JWT auth |
239
+ | `baseURL` | `string` | `http://localhost:3001` | API base URL (set to your production URL in deployed apps) |
240
+ | `maxRetries` | `number` | `2` | Max retries on transient errors |
241
+ | `timeout` | `number` | `60000` | Request timeout (ms) |
242
+
243
+ ---
244
+
245
+ ## License
246
+
247
+ MIT