@gpt-core/client 0.1.0-alpha.1 → 0.1.0-alpha.2

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/dist/index.mjs CHANGED
@@ -1354,9 +1354,131 @@ var EmbeddingService = class {
1354
1354
  }
1355
1355
  };
1356
1356
 
1357
+ // src/errors/index.ts
1358
+ var GptCoreError = class extends Error {
1359
+ constructor(message, options) {
1360
+ super(message);
1361
+ this.name = this.constructor.name;
1362
+ this.statusCode = options?.statusCode;
1363
+ this.code = options?.code;
1364
+ this.requestId = options?.requestId;
1365
+ this.headers = options?.headers;
1366
+ this.body = options?.body;
1367
+ if (options?.cause) {
1368
+ this.cause = options.cause;
1369
+ }
1370
+ if (Error.captureStackTrace) {
1371
+ Error.captureStackTrace(this, this.constructor);
1372
+ }
1373
+ }
1374
+ };
1375
+ var AuthenticationError = class extends GptCoreError {
1376
+ constructor(message = "Authentication failed", options) {
1377
+ super(message, { statusCode: 401, ...options });
1378
+ }
1379
+ };
1380
+ var AuthorizationError = class extends GptCoreError {
1381
+ constructor(message = "Permission denied", options) {
1382
+ super(message, { statusCode: 403, ...options });
1383
+ }
1384
+ };
1385
+ var NotFoundError = class extends GptCoreError {
1386
+ constructor(message = "Resource not found", options) {
1387
+ super(message, { statusCode: 404, ...options });
1388
+ }
1389
+ };
1390
+ var ValidationError = class extends GptCoreError {
1391
+ constructor(message = "Validation failed", errors, options) {
1392
+ super(message, { statusCode: 422, ...options });
1393
+ this.errors = errors;
1394
+ }
1395
+ };
1396
+ var RateLimitError = class extends GptCoreError {
1397
+ constructor(message = "Rate limit exceeded", retryAfter, options) {
1398
+ super(message, { statusCode: 429, ...options });
1399
+ this.retryAfter = retryAfter;
1400
+ }
1401
+ };
1402
+ var NetworkError = class extends GptCoreError {
1403
+ constructor(message = "Network request failed", options) {
1404
+ super(message, options);
1405
+ }
1406
+ };
1407
+ var TimeoutError = class extends GptCoreError {
1408
+ constructor(message = "Request timeout", options) {
1409
+ super(message, options);
1410
+ }
1411
+ };
1412
+ var ServerError = class extends GptCoreError {
1413
+ constructor(message = "Internal server error", options) {
1414
+ super(message, { statusCode: 500, ...options });
1415
+ }
1416
+ };
1417
+ function handleApiError(error) {
1418
+ const response = error?.response || error;
1419
+ const statusCode = response?.status || error?.status || error?.statusCode;
1420
+ const headers = response?.headers || error?.headers;
1421
+ const requestId = headers?.get?.("x-request-id") || headers?.["x-request-id"];
1422
+ const body = response?.body || response?.data || error?.body || error?.data || error;
1423
+ let message = "An error occurred";
1424
+ let errors;
1425
+ if (body?.errors && Array.isArray(body.errors)) {
1426
+ const firstError = body.errors[0];
1427
+ message = firstError?.title || firstError?.detail || message;
1428
+ errors = body.errors.map((err) => ({
1429
+ field: err.source?.pointer?.split("/").pop(),
1430
+ message: err.detail || err.title || "Unknown error"
1431
+ }));
1432
+ } else if (body?.message) {
1433
+ message = body.message;
1434
+ } else if (typeof body === "string") {
1435
+ message = body;
1436
+ } else if (error?.message) {
1437
+ message = error.message;
1438
+ }
1439
+ const errorOptions = {
1440
+ statusCode,
1441
+ requestId,
1442
+ headers: headers ? headers.entries ? Object.fromEntries(headers.entries()) : Object.fromEntries(Object.entries(headers)) : void 0,
1443
+ body,
1444
+ cause: error
1445
+ };
1446
+ switch (statusCode) {
1447
+ case 401:
1448
+ throw new AuthenticationError(message, errorOptions);
1449
+ case 403:
1450
+ throw new AuthorizationError(message, errorOptions);
1451
+ case 404:
1452
+ throw new NotFoundError(message, errorOptions);
1453
+ case 400:
1454
+ case 422:
1455
+ throw new ValidationError(message, errors, errorOptions);
1456
+ case 429:
1457
+ const retryAfter = headers?.get?.("retry-after") || headers?.["retry-after"];
1458
+ throw new RateLimitError(message, retryAfter ? parseInt(retryAfter, 10) : void 0, errorOptions);
1459
+ case 500:
1460
+ case 502:
1461
+ case 503:
1462
+ case 504:
1463
+ throw new ServerError(message, errorOptions);
1464
+ default:
1465
+ if (statusCode && statusCode >= 400) {
1466
+ throw new GptCoreError(message, errorOptions);
1467
+ }
1468
+ throw new NetworkError(message, errorOptions);
1469
+ }
1470
+ }
1471
+
1357
1472
  // src/base-client.ts
1358
1473
  var BaseClient = class {
1359
1474
  constructor(config = {}) {
1475
+ this.config = config;
1476
+ this.retryConfig = config.retry !== void 0 ? config.retry : {
1477
+ maxRetries: 3,
1478
+ initialDelay: 1e3,
1479
+ maxDelay: 32e3,
1480
+ retryableStatusCodes: [429, 500, 502, 503, 504]
1481
+ };
1360
1482
  if (config.baseUrl) {
1361
1483
  client.setConfig({ baseUrl: config.baseUrl });
1362
1484
  }
@@ -1371,6 +1493,12 @@ var BaseClient = class {
1371
1493
  }
1372
1494
  return req;
1373
1495
  });
1496
+ client.interceptors.response.use((response) => {
1497
+ if (response.error) {
1498
+ handleApiError(response.error);
1499
+ }
1500
+ return response;
1501
+ });
1374
1502
  }
1375
1503
  unwrap(resource) {
1376
1504
  if (!resource) return null;
@@ -1379,64 +1507,176 @@ var BaseClient = class {
1379
1507
  }
1380
1508
  return resource;
1381
1509
  }
1510
+ handleError(error) {
1511
+ return handleApiError(error);
1512
+ }
1382
1513
  };
1383
1514
 
1515
+ // src/pagination.ts
1516
+ async function* paginateAll(fetcher, options = {}) {
1517
+ const pageSize = options.pageSize || 20;
1518
+ const limit = options.limit;
1519
+ let page = 1;
1520
+ let totalYielded = 0;
1521
+ while (true) {
1522
+ const response = await fetcher(page, pageSize);
1523
+ for (const item of response.data) {
1524
+ yield item;
1525
+ totalYielded++;
1526
+ if (limit && totalYielded >= limit) {
1527
+ return;
1528
+ }
1529
+ }
1530
+ if (!response.links?.next || response.data.length === 0) {
1531
+ break;
1532
+ }
1533
+ page++;
1534
+ }
1535
+ }
1536
+ async function paginateToArray(fetcher, options = {}) {
1537
+ const results = [];
1538
+ for await (const item of paginateAll(fetcher, options)) {
1539
+ results.push(item);
1540
+ }
1541
+ return results;
1542
+ }
1543
+
1544
+ // src/schemas/requests.ts
1545
+ import { z } from "zod";
1546
+ var LoginRequestSchema = z.object({
1547
+ email: z.string().email(),
1548
+ password: z.string().min(8)
1549
+ });
1550
+ var RegisterRequestSchema = z.object({
1551
+ email: z.string().email(),
1552
+ password: z.string().min(8),
1553
+ password_confirmation: z.string().min(8)
1554
+ }).refine((data) => data.password === data.password_confirmation, {
1555
+ message: "Passwords don't match",
1556
+ path: ["password_confirmation"]
1557
+ });
1558
+ var ApiKeyCreateSchema = z.object({
1559
+ name: z.string().min(1).max(255)
1560
+ });
1561
+ var ApiKeyAllocateSchema = z.object({
1562
+ amount: z.number().positive(),
1563
+ description: z.string().min(1)
1564
+ });
1565
+ var ApplicationCreateSchema = z.object({
1566
+ name: z.string().min(1).max(255),
1567
+ slug: z.string().regex(/^[a-z0-9-]+$/).optional(),
1568
+ description: z.string().optional()
1569
+ });
1570
+ var WorkspaceCreateSchema = z.object({
1571
+ name: z.string().min(1).max(255),
1572
+ slug: z.string().regex(/^[a-z0-9-]+$/).optional()
1573
+ });
1574
+ var InvitationCreateSchema = z.object({
1575
+ email: z.string().email(),
1576
+ role: z.string(),
1577
+ scope_type: z.enum(["tenant", "workspace"]),
1578
+ scope_id: z.string().uuid()
1579
+ });
1580
+ var AgentCreateSchema = z.object({
1581
+ name: z.string().min(1).max(255),
1582
+ prompt_template: z.string().min(1)
1583
+ });
1584
+ var ThreadCreateSchema = z.object({
1585
+ title: z.string().max(255).optional()
1586
+ });
1587
+ var MessageSendSchema = z.object({
1588
+ content: z.string().min(1)
1589
+ });
1590
+ var SearchRequestSchema = z.object({
1591
+ query: z.string().min(1),
1592
+ top_k: z.number().int().positive().max(100).default(5)
1593
+ });
1594
+ var EmbedRequestSchema = z.object({
1595
+ text: z.string().min(1),
1596
+ workspace_id: z.string().uuid().optional()
1597
+ });
1598
+ var DocumentUploadBase64Schema = z.object({
1599
+ filename: z.string().min(1),
1600
+ content: z.string().min(1)
1601
+ // base64 content
1602
+ });
1603
+ var BucketCreateSchema = z.object({
1604
+ name: z.string().min(1).max(255),
1605
+ type: z.enum(["public", "private"])
1606
+ });
1607
+ var PresignedUploadSchema = z.object({
1608
+ filename: z.string().min(1),
1609
+ content_type: z.string().min(1)
1610
+ });
1611
+ var PresignedDownloadSchema = z.object({
1612
+ file_id: z.string().uuid()
1613
+ });
1614
+
1384
1615
  // src/gpt-client.ts
1385
1616
  var GptClient = class extends BaseClient {
1386
1617
  constructor(config) {
1387
1618
  super(config);
1388
1619
  this.identity = {
1389
1620
  login: async (email, password) => {
1621
+ const validated = LoginRequestSchema.parse({ email, password });
1390
1622
  const { data, error } = await UserService.postUsersAuthLogin({
1391
- body: { data: { type: "user", attributes: { email, password } } }
1623
+ body: {
1624
+ data: {
1625
+ type: "user",
1626
+ attributes: validated
1627
+ }
1628
+ }
1392
1629
  });
1393
- if (error) throw error;
1630
+ if (error) this.handleError(error);
1394
1631
  return {
1395
1632
  user: this.unwrap(data?.data),
1396
1633
  token: data?.meta?.token
1397
1634
  };
1398
1635
  },
1399
1636
  register: async (email, password, password_confirmation) => {
1637
+ const validated = RegisterRequestSchema.parse({ email, password, password_confirmation });
1400
1638
  const { data, error } = await UserService.postUsersAuthRegister({
1401
1639
  body: {
1402
1640
  data: {
1403
1641
  type: "user",
1404
- attributes: { email, password, password_confirmation }
1642
+ attributes: validated
1405
1643
  }
1406
1644
  }
1407
1645
  });
1408
- if (error) throw error;
1646
+ if (error) this.handleError(error);
1409
1647
  return this.unwrap(data?.data);
1410
1648
  },
1411
1649
  me: async () => {
1412
1650
  const { data, error } = await UserService.getUsersMe();
1413
- if (error) throw error;
1651
+ if (error) this.handleError(error);
1414
1652
  return this.unwrap(data?.data);
1415
1653
  },
1416
1654
  profile: async () => {
1417
1655
  const { data, error } = await UserProfileService.getUserProfilesMe();
1418
- if (error) throw error;
1656
+ if (error) this.handleError(error);
1419
1657
  return this.unwrap(data?.data);
1420
1658
  },
1421
1659
  apiKeys: {
1422
1660
  list: async () => {
1423
1661
  const { data, error } = await ApiKeyService.getApiKeys();
1424
- if (error) throw error;
1662
+ if (error) this.handleError(error);
1425
1663
  return this.unwrap(data?.data);
1426
1664
  },
1427
1665
  create: async (name) => {
1666
+ const validated = ApiKeyCreateSchema.parse({ name });
1428
1667
  const { data, error } = await ApiKeyService.postApiKeys({
1429
- body: { data: { type: "api_key", attributes: { name } } }
1668
+ body: { data: { type: "api_key", attributes: validated } }
1430
1669
  });
1431
- if (error) throw error;
1670
+ if (error) this.handleError(error);
1432
1671
  return this.unwrap(data?.data);
1433
1672
  },
1434
1673
  allocate: async (id, amount, description) => {
1674
+ const validated = ApiKeyAllocateSchema.parse({ amount, description });
1435
1675
  const { error } = await ApiKeyService.patchApiKeysByIdAllocate({
1436
1676
  path: { id },
1437
- body: { data: { type: "api_key", id, attributes: { amount, description } } }
1677
+ body: { data: { type: "api_key", id, attributes: validated } }
1438
1678
  });
1439
- if (error) throw error;
1679
+ if (error) this.handleError(error);
1440
1680
  return true;
1441
1681
  }
1442
1682
  }
@@ -1445,68 +1685,76 @@ var GptClient = class extends BaseClient {
1445
1685
  applications: {
1446
1686
  list: async () => {
1447
1687
  const { data, error } = await ApplicationService.getApplications();
1448
- if (error) throw error;
1688
+ if (error) this.handleError(error);
1449
1689
  return this.unwrap(data?.data);
1450
1690
  },
1451
1691
  create: async (attributes) => {
1692
+ const validated = ApplicationCreateSchema.parse(attributes);
1452
1693
  const { data, error } = await ApplicationService.postApplications({
1453
- body: { data: { type: "application", attributes } }
1694
+ body: { data: { type: "application", attributes: validated } }
1454
1695
  });
1455
- if (error) throw error;
1696
+ if (error) this.handleError(error);
1456
1697
  return this.unwrap(data?.data);
1457
1698
  },
1458
1699
  getBySlug: async (slug) => {
1459
1700
  const { data, error } = await ApplicationService.getApplicationsBySlugBySlug({
1460
1701
  path: { slug }
1461
1702
  });
1462
- if (error) throw error;
1703
+ if (error) this.handleError(error);
1463
1704
  return this.unwrap(data?.data);
1464
1705
  }
1465
1706
  },
1466
1707
  workspaces: {
1467
1708
  list: async () => {
1468
1709
  const { data, error } = await WorkspaceService.getWorkspaces();
1469
- if (error) throw error;
1710
+ if (error) this.handleError(error);
1470
1711
  return this.unwrap(data?.data);
1471
1712
  },
1472
1713
  mine: async () => {
1473
1714
  const { data, error } = await WorkspaceService.getWorkspacesMine();
1474
- if (error) throw error;
1715
+ if (error) this.handleError(error);
1475
1716
  return this.unwrap(data?.data);
1476
1717
  },
1477
1718
  create: async (name, slug) => {
1719
+ const validated = WorkspaceCreateSchema.parse({ name, slug });
1478
1720
  const { data, error } = await WorkspaceService.postWorkspaces({
1479
- body: { data: { type: "workspace", attributes: { name, slug } } }
1721
+ body: { data: { type: "workspace", attributes: validated } }
1480
1722
  });
1481
- if (error) throw error;
1723
+ if (error) this.handleError(error);
1482
1724
  return this.unwrap(data?.data);
1483
1725
  }
1484
1726
  },
1485
1727
  tenants: {
1486
1728
  list: async () => {
1487
1729
  const { data, error } = await TenantService.getTenants();
1488
- if (error) throw error;
1730
+ if (error) this.handleError(error);
1489
1731
  return this.unwrap(data?.data);
1490
1732
  }
1491
1733
  },
1492
1734
  invitations: {
1493
1735
  list: async () => {
1494
1736
  const { data, error } = await InvitationService.getInvitations();
1495
- if (error) throw error;
1737
+ if (error) this.handleError(error);
1496
1738
  return this.unwrap(data?.data);
1497
1739
  },
1498
1740
  invite: async (email, role2, scopeType, scopeId) => {
1741
+ const validated = InvitationCreateSchema.parse({
1742
+ email,
1743
+ role: role2,
1744
+ scope_type: scopeType,
1745
+ scope_id: scopeId
1746
+ });
1499
1747
  const { error } = await InvitationService.postInvitationsInvite({
1500
- body: { email, role: role2, scope_type: scopeType, scope_id: scopeId }
1748
+ body: validated
1501
1749
  });
1502
- if (error) throw error;
1750
+ if (error) this.handleError(error);
1503
1751
  return true;
1504
1752
  }
1505
1753
  },
1506
1754
  auditLogs: {
1507
1755
  list: async () => {
1508
1756
  const { data, error } = await AuditLogService.getAuditLogs();
1509
- if (error) throw error;
1757
+ if (error) this.handleError(error);
1510
1758
  return this.unwrap(data?.data);
1511
1759
  }
1512
1760
  }
@@ -1515,51 +1763,75 @@ var GptClient = class extends BaseClient {
1515
1763
  agents: {
1516
1764
  list: async () => {
1517
1765
  const { data, error } = await AgentService.getAgents();
1518
- if (error) throw error;
1766
+ if (error) this.handleError(error);
1519
1767
  return this.unwrap(data?.data);
1520
1768
  },
1521
1769
  create: async (name, promptTemplate) => {
1770
+ const validated = AgentCreateSchema.parse({ name, prompt_template: promptTemplate });
1522
1771
  const { data, error } = await AgentService.postAgents({
1523
- body: { data: { type: "agent", attributes: { name, prompt_template: promptTemplate } } }
1772
+ body: { data: { type: "agent", attributes: validated } }
1524
1773
  });
1525
- if (error) throw error;
1774
+ if (error) this.handleError(error);
1526
1775
  return this.unwrap(data?.data);
1527
1776
  }
1528
1777
  },
1529
1778
  threads: {
1530
1779
  list: async () => {
1531
1780
  const { data, error } = await ThreadService.getThreads();
1532
- if (error) throw error;
1781
+ if (error) this.handleError(error);
1533
1782
  return this.unwrap(data?.data);
1534
1783
  },
1535
1784
  create: async (title) => {
1785
+ const validated = ThreadCreateSchema.parse({ title });
1536
1786
  const { data, error } = await ThreadService.postThreads({
1537
- body: { data: { type: "thread", attributes: { title } } }
1787
+ body: { data: { type: "thread", attributes: validated } }
1538
1788
  });
1539
- if (error) throw error;
1789
+ if (error) this.handleError(error);
1540
1790
  return this.unwrap(data?.data);
1541
1791
  },
1542
1792
  sendMessage: async (threadId, content) => {
1793
+ const validated = MessageSendSchema.parse({ content });
1543
1794
  const { data, error } = await ThreadService.postThreadsByIdMessages({
1544
1795
  path: { id: threadId },
1545
- body: { data: { attributes: { content } } }
1796
+ body: { data: { attributes: validated } }
1546
1797
  });
1547
- if (error) throw error;
1798
+ if (error) this.handleError(error);
1548
1799
  return this.unwrap(data);
1549
1800
  }
1801
+ /**
1802
+ * Note: For streaming message responses, use the streaming utilities:
1803
+ *
1804
+ * ```typescript
1805
+ * import { streamMessage } from '@gpt-core/client';
1806
+ *
1807
+ * // Make streaming request to backend
1808
+ * const response = await fetch(`${baseUrl}/threads/${threadId}/messages/stream`, {
1809
+ * method: 'POST',
1810
+ * headers: { 'Accept': 'text/event-stream' },
1811
+ * body: JSON.stringify({ content: 'Hello' })
1812
+ * });
1813
+ *
1814
+ * // Stream the response
1815
+ * for await (const chunk of streamMessage(response)) {
1816
+ * console.log(chunk.content);
1817
+ * }
1818
+ * ```
1819
+ */
1550
1820
  },
1551
1821
  search: async (query, top_k = 5) => {
1822
+ const validated = SearchRequestSchema.parse({ query, top_k });
1552
1823
  const { data, error } = await SearchService.postAiSearch({
1553
- body: { query, top_k }
1824
+ body: validated
1554
1825
  });
1555
- if (error) throw error;
1826
+ if (error) this.handleError(error);
1556
1827
  return this.unwrap(data);
1557
1828
  },
1558
1829
  embed: async (text, workspaceId) => {
1830
+ const validated = EmbedRequestSchema.parse({ text, workspace_id: workspaceId });
1559
1831
  const { data, error } = await EmbeddingService.postAiEmbed({
1560
- body: { text, workspace_id: workspaceId }
1832
+ body: validated
1561
1833
  });
1562
- if (error) throw error;
1834
+ if (error) this.handleError(error);
1563
1835
  return this.unwrap(data);
1564
1836
  }
1565
1837
  };
@@ -1567,39 +1839,40 @@ var GptClient = class extends BaseClient {
1567
1839
  documents: {
1568
1840
  list: async () => {
1569
1841
  const { data, error } = await DocumentService.getDocuments();
1570
- if (error) throw error;
1842
+ if (error) this.handleError(error);
1571
1843
  return this.unwrap(data?.data);
1572
1844
  },
1573
1845
  upload: async (_file, _filename) => {
1574
1846
  throw new Error("Use uploadBase64 for now");
1575
1847
  },
1576
1848
  uploadBase64: async (filename, base64Content) => {
1849
+ const validated = DocumentUploadBase64Schema.parse({ filename, content: base64Content });
1577
1850
  const { data, error } = await DocumentService.postDocuments({
1578
- body: { data: { type: "document", attributes: { filename, content: base64Content } } }
1851
+ body: { data: { type: "document", attributes: validated } }
1579
1852
  });
1580
- if (error) throw error;
1853
+ if (error) this.handleError(error);
1581
1854
  return this.unwrap(data?.data);
1582
1855
  },
1583
1856
  get: async (id) => {
1584
1857
  const { data, error } = await DocumentService.getDocumentsById({ path: { id } });
1585
- if (error) throw error;
1858
+ if (error) this.handleError(error);
1586
1859
  return this.unwrap(data?.data);
1587
1860
  },
1588
1861
  delete: async (id) => {
1589
1862
  const { error } = await DocumentService.deleteDocumentsById({ path: { id } });
1590
- if (error) throw error;
1863
+ if (error) this.handleError(error);
1591
1864
  return true;
1592
1865
  },
1593
1866
  analyze: async (id) => {
1594
1867
  const { error } = await DocumentService.postDocumentsByIdAnalyze({ path: { id }, body: {} });
1595
- if (error) throw error;
1868
+ if (error) this.handleError(error);
1596
1869
  return true;
1597
1870
  }
1598
1871
  },
1599
1872
  results: {
1600
1873
  list: async () => {
1601
1874
  const { data, error } = await ExtractionResultService.getExtractionResults();
1602
- if (error) throw error;
1875
+ if (error) this.handleError(error);
1603
1876
  return this.unwrap(data?.data);
1604
1877
  }
1605
1878
  }
@@ -1608,30 +1881,33 @@ var GptClient = class extends BaseClient {
1608
1881
  buckets: {
1609
1882
  list: async () => {
1610
1883
  const { data, error } = await BucketService.getBuckets();
1611
- if (error) throw error;
1884
+ if (error) this.handleError(error);
1612
1885
  return this.unwrap(data?.data);
1613
1886
  },
1614
1887
  create: async (name, isPublic = false) => {
1888
+ const validated = BucketCreateSchema.parse({ name, type: isPublic ? "public" : "private" });
1615
1889
  const { data, error } = await BucketService.postBuckets({
1616
- body: { data: { type: "bucket", attributes: { name, type: isPublic ? "public" : "private" } } }
1890
+ body: { data: { type: "bucket", attributes: validated } }
1617
1891
  });
1618
- if (error) throw error;
1892
+ if (error) this.handleError(error);
1619
1893
  return this.unwrap(data?.data);
1620
1894
  }
1621
1895
  },
1622
1896
  presigned: {
1623
1897
  upload: async (filename, contentType) => {
1898
+ const validated = PresignedUploadSchema.parse({ filename, content_type: contentType });
1624
1899
  const { data, error } = await PresignedUrlService.postStorageSignUpload({
1625
- body: { filename, content_type: contentType }
1900
+ body: validated
1626
1901
  });
1627
- if (error) throw error;
1902
+ if (error) this.handleError(error);
1628
1903
  return this.unwrap(data);
1629
1904
  },
1630
1905
  download: async (fileId) => {
1906
+ const validated = PresignedDownloadSchema.parse({ file_id: fileId });
1631
1907
  const { data, error } = await PresignedUrlService.postStorageSignDownload({
1632
- body: { file_id: fileId }
1908
+ body: validated
1633
1909
  });
1634
- if (error) throw error;
1910
+ if (error) this.handleError(error);
1635
1911
  return this.unwrap(data);
1636
1912
  }
1637
1913
  }
@@ -1640,14 +1916,14 @@ var GptClient = class extends BaseClient {
1640
1916
  wallet: {
1641
1917
  get: async () => {
1642
1918
  const { data, error } = await WalletService.getWallet();
1643
- if (error) throw error;
1919
+ if (error) this.handleError(error);
1644
1920
  return this.unwrap(data?.data);
1645
1921
  }
1646
1922
  },
1647
1923
  plans: {
1648
1924
  list: async () => {
1649
1925
  const { data, error } = await PlanService.getPlans();
1650
- if (error) throw error;
1926
+ if (error) this.handleError(error);
1651
1927
  return this.unwrap(data?.data);
1652
1928
  }
1653
1929
  }
@@ -1928,8 +2204,157 @@ var type = {
1928
2204
  PUBLIC: "public",
1929
2205
  PRIVATE: "private"
1930
2206
  };
2207
+
2208
+ // src/utils/retry.ts
2209
+ var DEFAULT_RETRY_CONFIG = {
2210
+ maxRetries: 3,
2211
+ initialDelay: 1e3,
2212
+ // 1 second
2213
+ maxDelay: 32e3,
2214
+ // 32 seconds
2215
+ retryableStatusCodes: [429, 500, 502, 503, 504]
2216
+ };
2217
+ function isRetryableError(error, retryableStatusCodes) {
2218
+ const statusCode = error?.status || error?.statusCode || error?.response?.status;
2219
+ return retryableStatusCodes.includes(statusCode);
2220
+ }
2221
+ function calculateBackoff(attempt, initialDelay, maxDelay, retryAfter) {
2222
+ if (retryAfter) {
2223
+ return Math.min(retryAfter * 1e3, maxDelay);
2224
+ }
2225
+ const exponentialDelay = initialDelay * Math.pow(2, attempt);
2226
+ const jitter = Math.random() * 0.3 * exponentialDelay;
2227
+ const delay = exponentialDelay + jitter;
2228
+ return Math.min(delay, maxDelay);
2229
+ }
2230
+ function sleep(ms) {
2231
+ return new Promise((resolve) => setTimeout(resolve, ms));
2232
+ }
2233
+ async function retryWithBackoff(fn, config = DEFAULT_RETRY_CONFIG) {
2234
+ let lastError;
2235
+ for (let attempt = 0; attempt <= config.maxRetries; attempt++) {
2236
+ try {
2237
+ return await fn();
2238
+ } catch (error) {
2239
+ lastError = error;
2240
+ if (attempt === config.maxRetries || !isRetryableError(error, config.retryableStatusCodes)) {
2241
+ throw error;
2242
+ }
2243
+ const errorWithHeaders = error;
2244
+ const retryAfter = errorWithHeaders?.response?.headers?.get?.("retry-after") || errorWithHeaders?.response?.headers?.["retry-after"] || errorWithHeaders?.headers?.get?.("retry-after") || errorWithHeaders?.headers?.["retry-after"];
2245
+ const retryAfterSeconds = retryAfter ? parseInt(retryAfter, 10) : void 0;
2246
+ const delay = calculateBackoff(
2247
+ attempt,
2248
+ config.initialDelay,
2249
+ config.maxDelay,
2250
+ retryAfterSeconds
2251
+ );
2252
+ await sleep(delay);
2253
+ }
2254
+ }
2255
+ throw lastError;
2256
+ }
2257
+ function withRetry(fn, config) {
2258
+ const retryConfig = { ...DEFAULT_RETRY_CONFIG, ...config };
2259
+ return async (...args) => {
2260
+ return retryWithBackoff(() => fn(...args), retryConfig);
2261
+ };
2262
+ }
2263
+
2264
+ // src/streaming.ts
2265
+ async function* streamSSE(response, options = {}) {
2266
+ if (!response.body) {
2267
+ throw new Error("Response body is null");
2268
+ }
2269
+ const reader = response.body.getReader();
2270
+ const decoder = new TextDecoder();
2271
+ let buffer = "";
2272
+ try {
2273
+ while (true) {
2274
+ const { done, value } = await reader.read();
2275
+ if (done) {
2276
+ break;
2277
+ }
2278
+ if (options.signal?.aborted) {
2279
+ reader.cancel();
2280
+ throw new Error("Stream aborted");
2281
+ }
2282
+ buffer += decoder.decode(value, { stream: true });
2283
+ const lines = buffer.split("\n");
2284
+ buffer = lines.pop() || "";
2285
+ for (const line of lines) {
2286
+ if (line.startsWith("data: ")) {
2287
+ const data = line.slice(6);
2288
+ if (data === "[DONE]" || data.trim() === "") {
2289
+ continue;
2290
+ }
2291
+ try {
2292
+ const parsed = JSON.parse(data);
2293
+ yield parsed;
2294
+ } catch (e) {
2295
+ yield data;
2296
+ }
2297
+ }
2298
+ }
2299
+ }
2300
+ } catch (error) {
2301
+ if (options.onError) {
2302
+ options.onError(error);
2303
+ }
2304
+ throw error;
2305
+ } finally {
2306
+ reader.releaseLock();
2307
+ }
2308
+ }
2309
+ async function* streamMessage(response, options = {}) {
2310
+ for await (const chunk of streamSSE(response, options)) {
2311
+ yield chunk;
2312
+ if (chunk.type === "done" || chunk.type === "error") {
2313
+ break;
2314
+ }
2315
+ }
2316
+ }
2317
+ async function collectStreamedMessage(stream) {
2318
+ let fullMessage = "";
2319
+ for await (const chunk of stream) {
2320
+ if (chunk.type === "content" && chunk.content) {
2321
+ fullMessage += chunk.content;
2322
+ } else if (chunk.type === "error") {
2323
+ throw new Error(chunk.error || "Stream error");
2324
+ }
2325
+ }
2326
+ return fullMessage;
2327
+ }
1931
2328
  export {
2329
+ AgentCreateSchema,
2330
+ ApiKeyAllocateSchema,
2331
+ ApiKeyCreateSchema,
2332
+ ApplicationCreateSchema,
2333
+ AuthenticationError,
2334
+ AuthorizationError,
2335
+ BucketCreateSchema,
2336
+ DEFAULT_RETRY_CONFIG,
2337
+ DocumentUploadBase64Schema,
2338
+ EmbedRequestSchema,
1932
2339
  GptClient,
2340
+ GptCoreError,
2341
+ InvitationCreateSchema,
2342
+ LoginRequestSchema,
2343
+ MessageSendSchema,
2344
+ NetworkError,
2345
+ NotFoundError,
2346
+ PresignedDownloadSchema,
2347
+ PresignedUploadSchema,
2348
+ RateLimitError,
2349
+ RegisterRequestSchema,
2350
+ SearchRequestSchema,
2351
+ ServerError,
2352
+ ThreadCreateSchema,
2353
+ TimeoutError,
2354
+ ValidationError,
2355
+ WorkspaceCreateSchema,
2356
+ calculateBackoff,
2357
+ collectStreamedMessage,
1933
2358
  eq,
1934
2359
  eq2,
1935
2360
  eq3,
@@ -1955,6 +2380,8 @@ export {
1955
2380
  greater_than_or_equal6,
1956
2381
  greater_than_or_equal7,
1957
2382
  greater_than_or_equal8,
2383
+ handleApiError,
2384
+ isRetryableError,
1958
2385
  less_than,
1959
2386
  less_than2,
1960
2387
  less_than3,
@@ -1979,8 +2406,15 @@ export {
1979
2406
  not_eq6,
1980
2407
  not_eq7,
1981
2408
  not_eq8,
2409
+ paginateAll,
2410
+ paginateToArray,
2411
+ retryWithBackoff,
1982
2412
  role,
2413
+ sleep,
1983
2414
  status,
1984
2415
  status2,
1985
- type
2416
+ streamMessage,
2417
+ streamSSE,
2418
+ type,
2419
+ withRetry
1986
2420
  };