@gpt-core/client 0.10.13 → 0.10.21

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
@@ -29,8 +29,11 @@ AI_CONTEXT_END -->
29
29
  > **TL;DR for Claude, Cursor, Copilot, and other AI assistants:**
30
30
  >
31
31
  > ```typescript
32
- > import { GptClient } from '@gpt-core/client';
33
- > const client = new GptClient({ baseUrl: 'https://api.example.com', token: 'jwt' });
32
+ > import { GptClient } from "@gpt-core/client";
33
+ > const client = new GptClient({
34
+ > baseUrl: "https://api.example.com",
35
+ > token: "jwt",
36
+ > });
34
37
  > ```
35
38
  >
36
39
  > **Common operations:**
@@ -70,26 +73,26 @@ pnpm add @gpt-core/client
70
73
  ## Quick Start
71
74
 
72
75
  ```typescript
73
- import { GptClient } from '@gpt-core/client';
76
+ import { GptClient } from "@gpt-core/client";
74
77
 
75
78
  // Initialize client
76
79
  const client = new GptClient({
77
- baseUrl: 'https://api.gpt-core.com',
78
- apiKey: 'your-api-key', // For machine-to-machine
79
- token: 'user-jwt-token', // For user-authenticated requests
80
+ baseUrl: "https://api.gpt-core.com",
81
+ apiKey: "your-api-key", // For machine-to-machine
82
+ token: "user-jwt-token", // For user-authenticated requests
80
83
  });
81
84
 
82
85
  // Authenticate a user
83
86
  const { user, token } = await client.identity.login(
84
- 'user@example.com',
85
- 'password'
87
+ "user@example.com",
88
+ "password",
86
89
  );
87
90
 
88
91
  console.log(`Welcome, ${user.attributes.full_name}!`);
89
92
 
90
93
  // Use the token for subsequent requests
91
94
  const authenticatedClient = new GptClient({
92
- baseUrl: 'https://api.gpt-core.com',
95
+ baseUrl: "https://api.gpt-core.com",
93
96
  token: token,
94
97
  });
95
98
 
@@ -117,9 +120,9 @@ Pin a specific API version to protect your integration from breaking changes:
117
120
 
118
121
  ```typescript
119
122
  const client = new GptClient({
120
- baseUrl: 'https://api.gpt-core.com',
121
- apiKey: 'sk_live_...',
122
- apiVersion: '2025-12-03', // Pin to this version
123
+ baseUrl: "https://api.gpt-core.com",
124
+ apiKey: "sk_live_...",
125
+ apiVersion: "2025-12-03", // Pin to this version
123
126
  });
124
127
  ```
125
128
 
@@ -153,18 +156,29 @@ This returns the full list of versions with descriptions and deprecation status.
153
156
  ```typescript
154
157
  const client = new GptClient({
155
158
  // Required: API base URL
156
- baseUrl: 'https://api.gpt-core.com',
159
+ baseUrl: "https://api.gpt-core.com",
157
160
 
158
161
  // Authentication (provide one or both)
159
- apiKey: 'sk_live_...', // Application API key
160
- token: 'eyJhbGc...', // User JWT token
162
+ apiKey: "sk_live_...", // Application API key
163
+ token: "eyJhbGc...", // User JWT token
164
+
165
+ // API version (optional, uses SDK default if not specified)
166
+ apiVersion: "2025-12-03",
167
+
168
+ // Security configuration (optional)
169
+ security: {
170
+ requireHttps: false, // Throw error on HTTP (default: warn only)
171
+ warnBrowserApiKey: true, // Warn about API keys in browser (default: true)
172
+ },
161
173
 
162
174
  // Retry configuration (optional)
163
175
  retry: {
164
- maxRetries: 3, // Default: 3
165
- minTimeout: 1000, // Default: 1000ms
166
- maxTimeout: 30000, // Default: 30000ms
167
- randomize: true, // Default: true (adds jitter)
176
+ maxRetries: 3, // Default: 3
177
+ initialDelay: 1000, // Default: 1000ms (renamed from minTimeout)
178
+ maxDelay: 32000, // Default: 32000ms (renamed from maxTimeout)
179
+ retryableStatusCodes: [429, 500, 502, 503, 504],
180
+ totalTimeout: 300000, // Total timeout across all retries (ms)
181
+ maxRetryAfter: 60, // Max Retry-After header value (seconds)
168
182
  },
169
183
 
170
184
  // Disable retries
@@ -172,6 +186,54 @@ const client = new GptClient({
172
186
  });
173
187
  ```
174
188
 
189
+ ## Security Options
190
+
191
+ | Option | Type | Default | Description |
192
+ | ------------------- | ------- | ------- | ------------------------------------------------- |
193
+ | `requireHttps` | boolean | `false` | Throw `InsecureConnectionError` on non-HTTPS URLs |
194
+ | `warnBrowserApiKey` | boolean | `true` | Warn when API key detected in browser environment |
195
+
196
+ ### HTTPS Enforcement
197
+
198
+ ```typescript
199
+ // Development: Warns only
200
+ const devClient = new GptClient({
201
+ baseUrl: "http://localhost:22222",
202
+ apiKey: process.env.API_KEY,
203
+ security: { requireHttps: false },
204
+ });
205
+
206
+ // Production: Blocks HTTP
207
+ const prodClient = new GptClient({
208
+ baseUrl: "https://api.gpt-core.com",
209
+ apiKey: process.env.API_KEY,
210
+ security: { requireHttps: true },
211
+ });
212
+
213
+ try {
214
+ await prodClient.agents.list();
215
+ } catch (error) {
216
+ if (error instanceof InsecureConnectionError) {
217
+ console.error("Cannot use HTTP in production");
218
+ }
219
+ }
220
+ ```
221
+
222
+ ### API Key Validation
223
+
224
+ The SDK validates API key format and warns about elevated privilege keys:
225
+
226
+ ```typescript
227
+ // Valid keys: sk_tenant_*, sk_app_*, sk_srv_*, sk_sys_*
228
+ // sk_sys_* keys trigger warnings (elevated privileges)
229
+
230
+ const client = new GptClient({
231
+ apiKey: "sk_sys_abc123",
232
+ });
233
+ // [GPT Core SDK] Using system-level API key (sk_sys_).
234
+ // Ensure this is intended for platform operations.
235
+ ```
236
+
175
237
  ## API Reference
176
238
 
177
239
  ### Identity
@@ -183,7 +245,11 @@ Manage users, authentication, and API keys.
183
245
  const { user, token } = await client.identity.login(email, password);
184
246
 
185
247
  // Register
186
- const user = await client.identity.register(email, password, passwordConfirmation);
248
+ const user = await client.identity.register(
249
+ email,
250
+ password,
251
+ passwordConfirmation,
252
+ );
187
253
 
188
254
  // Get current user
189
255
  const user = await client.identity.me();
@@ -193,8 +259,8 @@ const profile = await client.identity.profile();
193
259
 
194
260
  // API Keys
195
261
  const keys = await client.identity.apiKeys.list();
196
- const newKey = await client.identity.apiKeys.create('Production Key');
197
- await client.identity.apiKeys.allocate('key-id', 1000, 'Monthly credits');
262
+ const newKey = await client.identity.apiKeys.create("Production Key");
263
+ await client.identity.apiKeys.allocate("key-id", 1000, "Monthly credits");
198
264
  ```
199
265
 
200
266
  ### Platform
@@ -205,22 +271,25 @@ Manage applications, workspaces, and tenants.
205
271
  // Applications
206
272
  const apps = await client.platform.applications.list();
207
273
  const app = await client.platform.applications.create({
208
- name: 'My App',
209
- slug: 'my-app',
274
+ name: "My App",
275
+ slug: "my-app",
210
276
  });
211
- const app = await client.platform.applications.getBySlug('my-app');
277
+ const app = await client.platform.applications.getBySlug("my-app");
212
278
 
213
279
  // Workspaces
214
280
  const workspaces = await client.platform.workspaces.list();
215
281
  const myWorkspaces = await client.platform.workspaces.mine();
216
- const workspace = await client.platform.workspaces.create('New Workspace', 'new-workspace');
282
+ const workspace = await client.platform.workspaces.create(
283
+ "New Workspace",
284
+ "new-workspace",
285
+ );
217
286
 
218
287
  // Invitations
219
288
  await client.platform.invitations.invite(
220
- 'colleague@example.com',
221
- 'editor',
222
- 'workspace',
223
- 'workspace-id'
289
+ "colleague@example.com",
290
+ "editor",
291
+ "workspace",
292
+ "workspace-id",
224
293
  );
225
294
  ```
226
295
 
@@ -232,20 +301,20 @@ Interact with agents, threads, and semantic search.
232
301
  // Agents
233
302
  const agents = await client.ai.agents.list();
234
303
  const agent = await client.ai.agents.create(
235
- 'Support Agent',
236
- 'You are a helpful customer support agent'
304
+ "Support Agent",
305
+ "You are a helpful customer support agent",
237
306
  );
238
307
 
239
308
  // Threads (Conversations)
240
309
  const threads = await client.ai.threads.list();
241
- const thread = await client.ai.threads.create('Bug Report Discussion');
242
- const message = await client.ai.threads.sendMessage(thread.id, 'Hello AI!');
310
+ const thread = await client.ai.threads.create("Bug Report Discussion");
311
+ const message = await client.ai.threads.sendMessage(thread.id, "Hello AI!");
243
312
 
244
313
  // Search
245
- const results = await client.ai.search('quarterly earnings', 10);
314
+ const results = await client.ai.search("quarterly earnings", 10);
246
315
 
247
316
  // Embeddings
248
- const embedding = await client.ai.embed('text to embed');
317
+ const embedding = await client.ai.embed("text to embed");
249
318
  ```
250
319
 
251
320
  ### Extraction
@@ -258,18 +327,18 @@ const documents = await client.extraction.documents.list();
258
327
 
259
328
  // Upload (base64)
260
329
  const doc = await client.extraction.documents.uploadBase64(
261
- 'report.pdf',
262
- base64Content
330
+ "report.pdf",
331
+ base64Content,
263
332
  );
264
333
 
265
334
  // Analyze
266
335
  await client.extraction.documents.analyze(doc.id);
267
336
 
268
337
  // Retrieve
269
- const doc = await client.extraction.documents.get('doc-id');
338
+ const doc = await client.extraction.documents.get("doc-id");
270
339
 
271
340
  // Delete
272
- await client.extraction.documents.delete('doc-id');
341
+ await client.extraction.documents.delete("doc-id");
273
342
 
274
343
  // Results
275
344
  const results = await client.extraction.results.list();
@@ -282,14 +351,14 @@ Manage buckets and files.
282
351
  ```typescript
283
352
  // Buckets
284
353
  const buckets = await client.storage.buckets.list();
285
- const bucket = await client.storage.buckets.create('uploads', false);
354
+ const bucket = await client.storage.buckets.create("uploads", false);
286
355
 
287
356
  // Presigned URLs
288
357
  const uploadUrl = await client.storage.presigned.upload(
289
- 'image.png',
290
- 'image/png'
358
+ "image.png",
359
+ "image/png",
291
360
  );
292
- const downloadUrl = await client.storage.presigned.download('file-id');
361
+ const downloadUrl = await client.storage.presigned.download("file-id");
293
362
  ```
294
363
 
295
364
  ### Billing
@@ -318,16 +387,16 @@ import {
318
387
  ValidationError,
319
388
  RateLimitError,
320
389
  ServerError,
321
- } from '@gpt-core/client';
390
+ } from "@gpt-core/client";
322
391
 
323
392
  try {
324
- await client.identity.login('user@example.com', 'wrong-password');
393
+ await client.identity.login("user@example.com", "wrong-password");
325
394
  } catch (error) {
326
395
  if (error instanceof AuthenticationError) {
327
- console.error('Invalid credentials:', error.message);
328
- console.error('Request ID:', error.requestId);
396
+ console.error("Invalid credentials:", error.message);
397
+ console.error("Request ID:", error.requestId);
329
398
  } else if (error instanceof ValidationError) {
330
- console.error('Validation errors:', error.errors);
399
+ console.error("Validation errors:", error.errors);
331
400
  } else if (error instanceof RateLimitError) {
332
401
  console.error(`Rate limited. Retry after ${error.retryAfter}s`);
333
402
  }
@@ -336,39 +405,50 @@ try {
336
405
 
337
406
  ### Pagination
338
407
 
339
- Easily iterate over large datasets:
408
+ Easily iterate over large datasets with built-in memory protection:
340
409
 
341
410
  ```typescript
342
- import { paginateAll } from '@gpt-core/client';
411
+ import { paginateAll } from "@gpt-core/client";
343
412
 
344
413
  // Using async iteration
345
414
  for await (const workspace of client.platform.workspaces.listAll()) {
346
415
  console.log(workspace.attributes.name);
347
416
  }
348
417
 
349
- // With limit
418
+ // With limit (default: 10,000)
350
419
  for await (const doc of client.extraction.documents.listAll({ limit: 100 })) {
351
420
  console.log(doc.attributes.filename);
352
421
  }
422
+
423
+ // Custom page size
424
+ for await (const item of paginateAll(fetcher, { pageSize: 50, limit: 1000 })) {
425
+ // Process items
426
+ }
353
427
  ```
354
428
 
429
+ **Pagination Safety:**
430
+
431
+ - **Default Limit**: 10,000 items max (prevents memory exhaustion)
432
+ - **Warning**: Shows warning when fetching > 1,000 items
433
+ - **Configurable**: Set custom `limit` for your use case
434
+
355
435
  ### Streaming
356
436
 
357
437
  Stream AI responses in real-time:
358
438
 
359
439
  ```typescript
360
- import { streamMessage } from '@gpt-core/client';
440
+ import { streamMessage } from "@gpt-core/client";
361
441
 
362
442
  // Make streaming request
363
443
  const response = await fetch(streamingEndpoint, {
364
- method: 'POST',
365
- headers: { 'Accept': 'text/event-stream' },
366
- body: JSON.stringify({ content: 'Hello AI' }),
444
+ method: "POST",
445
+ headers: { Accept: "text/event-stream" },
446
+ body: JSON.stringify({ content: "Hello AI" }),
367
447
  });
368
448
 
369
449
  // Stream the response
370
450
  for await (const chunk of streamMessage(response)) {
371
- if (chunk.type === 'content') {
451
+ if (chunk.type === "content") {
372
452
  process.stdout.write(chunk.content); // Real-time output
373
453
  }
374
454
  }
@@ -376,38 +456,60 @@ for await (const chunk of streamMessage(response)) {
376
456
 
377
457
  ### Retry Logic
378
458
 
379
- Automatic retries with exponential backoff:
459
+ Automatic retries with exponential backoff and circuit breaker:
380
460
 
381
461
  ```typescript
382
- // Retries are enabled by default
462
+ // Retries are enabled by default with circuit breaker protection
383
463
  const client = new GptClient({
384
- baseUrl: 'https://api.gpt-core.com',
385
- token: 'token',
464
+ baseUrl: "https://api.gpt-core.com",
465
+ token: "token",
386
466
  retry: {
387
- maxRetries: 5, // Retry up to 5 times
388
- minTimeout: 2000, // Start with 2s delay
467
+ maxRetries: 5, // Retry up to 5 times
468
+ initialDelay: 1000, // Start with 1s delay
469
+ maxDelay: 32000, // Max delay between retries
470
+ totalTimeout: 300000, // Total timeout (5 min) prevents infinite loops
471
+ maxRetryAfter: 60, // Cap Retry-After header to 60s
389
472
  },
390
473
  });
391
474
 
392
475
  // Disable retries for specific operations
393
476
  const noRetryClient = new GptClient({
394
- baseUrl: 'https://api.gpt-core.com',
395
- token: 'token',
477
+ baseUrl: "https://api.gpt-core.com",
478
+ token: "token",
396
479
  retry: false,
397
480
  });
398
481
  ```
399
482
 
483
+ **Retry Behavior:**
484
+
485
+ - **Circuit Breaker**: Total timeout prevents unbounded retry loops
486
+ - **Retry-After Validation**: Server Retry-After headers capped at 60 seconds
487
+ - **Jitter**: Random delay added to prevent thundering herd
488
+ - **Protected Status Codes**: 429, 500, 502, 503, 504
489
+
490
+ ```typescript
491
+ import { RetryTimeoutError } from "@gpt-core/client";
492
+
493
+ try {
494
+ await client.agents.list();
495
+ } catch (error) {
496
+ if (error instanceof RetryTimeoutError) {
497
+ console.error("Retry timeout exceeded:", error.message);
498
+ }
499
+ }
500
+ ```
501
+
400
502
  ## TypeScript Support
401
503
 
402
504
  The SDK is written in TypeScript and provides full type safety:
403
505
 
404
506
  ```typescript
405
- import type { user, workspace, document } from '@gpt-core/client';
507
+ import type { user, workspace, document } from "@gpt-core/client";
406
508
 
407
509
  const user: user = await client.identity.me();
408
510
  // TypeScript knows: user.attributes.email, user.id, etc.
409
511
 
410
- const workspace: workspace = await client.platform.workspaces.create('Test');
512
+ const workspace: workspace = await client.platform.workspaces.create("Test");
411
513
  // TypeScript enforces correct parameters
412
514
  ```
413
515