@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/README.md +306 -23
- package/dist/index.d.mts +390 -2
- package/dist/index.d.ts +390 -2
- package/dist/index.js +525 -54
- package/dist/index.mjs +487 -53
- package/package.json +10 -3
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: {
|
|
1623
|
+
body: {
|
|
1624
|
+
data: {
|
|
1625
|
+
type: "user",
|
|
1626
|
+
attributes: validated
|
|
1627
|
+
}
|
|
1628
|
+
}
|
|
1392
1629
|
});
|
|
1393
|
-
if (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:
|
|
1642
|
+
attributes: validated
|
|
1405
1643
|
}
|
|
1406
1644
|
}
|
|
1407
1645
|
});
|
|
1408
|
-
if (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)
|
|
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)
|
|
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)
|
|
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:
|
|
1668
|
+
body: { data: { type: "api_key", attributes: validated } }
|
|
1430
1669
|
});
|
|
1431
|
-
if (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:
|
|
1677
|
+
body: { data: { type: "api_key", id, attributes: validated } }
|
|
1438
1678
|
});
|
|
1439
|
-
if (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)
|
|
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)
|
|
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)
|
|
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)
|
|
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)
|
|
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:
|
|
1721
|
+
body: { data: { type: "workspace", attributes: validated } }
|
|
1480
1722
|
});
|
|
1481
|
-
if (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)
|
|
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)
|
|
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:
|
|
1748
|
+
body: validated
|
|
1501
1749
|
});
|
|
1502
|
-
if (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)
|
|
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)
|
|
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:
|
|
1772
|
+
body: { data: { type: "agent", attributes: validated } }
|
|
1524
1773
|
});
|
|
1525
|
-
if (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)
|
|
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:
|
|
1787
|
+
body: { data: { type: "thread", attributes: validated } }
|
|
1538
1788
|
});
|
|
1539
|
-
if (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:
|
|
1796
|
+
body: { data: { attributes: validated } }
|
|
1546
1797
|
});
|
|
1547
|
-
if (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:
|
|
1824
|
+
body: validated
|
|
1554
1825
|
});
|
|
1555
|
-
if (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:
|
|
1832
|
+
body: validated
|
|
1561
1833
|
});
|
|
1562
|
-
if (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)
|
|
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:
|
|
1851
|
+
body: { data: { type: "document", attributes: validated } }
|
|
1579
1852
|
});
|
|
1580
|
-
if (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)
|
|
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)
|
|
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)
|
|
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)
|
|
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)
|
|
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:
|
|
1890
|
+
body: { data: { type: "bucket", attributes: validated } }
|
|
1617
1891
|
});
|
|
1618
|
-
if (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:
|
|
1900
|
+
body: validated
|
|
1626
1901
|
});
|
|
1627
|
-
if (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:
|
|
1908
|
+
body: validated
|
|
1633
1909
|
});
|
|
1634
|
-
if (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)
|
|
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)
|
|
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
|
-
|
|
2416
|
+
streamMessage,
|
|
2417
|
+
streamSSE,
|
|
2418
|
+
type,
|
|
2419
|
+
withRetry
|
|
1986
2420
|
};
|