@gpt-core/client 0.10.12 → 0.10.20

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.js CHANGED
@@ -41,6 +41,7 @@ __export(index_exports, {
41
41
  PresignedUploadSchema: () => PresignedUploadSchema,
42
42
  RateLimitError: () => RateLimitError,
43
43
  RegisterRequestSchema: () => RegisterRequestSchema,
44
+ RetryTimeoutError: () => RetryTimeoutError,
44
45
  SearchRequestSchema: () => SearchRequestSchema,
45
46
  ServerError: () => ServerError,
46
47
  ThreadCreateSchema: () => ThreadCreateSchema,
@@ -152,6 +153,7 @@ __export(index_exports, {
152
153
  getExtractionResults: () => getExtractionResults,
153
154
  getExtractionResultsById: () => getExtractionResultsById,
154
155
  getExtractionResultsDocumentByDocumentId: () => getExtractionResultsDocumentByDocumentId,
156
+ getExtractionResultsDocumentByDocumentIdHistory: () => getExtractionResultsDocumentByDocumentIdHistory,
155
157
  getExtractionResultsWorkspaceByWorkspaceId: () => getExtractionResultsWorkspaceByWorkspaceId,
156
158
  getExtractionSchemaDiscoveriesById: () => getExtractionSchemaDiscoveriesById,
157
159
  getFieldTemplates: () => getFieldTemplates,
@@ -570,6 +572,7 @@ __export(sdk_gen_exports, {
570
572
  getExtractionResults: () => getExtractionResults,
571
573
  getExtractionResultsById: () => getExtractionResultsById,
572
574
  getExtractionResultsDocumentByDocumentId: () => getExtractionResultsDocumentByDocumentId,
575
+ getExtractionResultsDocumentByDocumentIdHistory: () => getExtractionResultsDocumentByDocumentIdHistory,
573
576
  getExtractionResultsWorkspaceByWorkspaceId: () => getExtractionResultsWorkspaceByWorkspaceId,
574
577
  getExtractionSchemaDiscoveriesById: () => getExtractionSchemaDiscoveriesById,
575
578
  getFieldTemplates: () => getFieldTemplates,
@@ -1813,7 +1816,12 @@ var patchApiKeysByIdRevoke = (options) => (options.client ?? client).patch({
1813
1816
  }
1814
1817
  });
1815
1818
  var getAiChunksDocumentByDocumentId = (options) => (options.client ?? client).get({
1816
- querySerializer: { parameters: { fields: { object: { style: "form" } } } },
1819
+ querySerializer: {
1820
+ parameters: {
1821
+ filter: { object: { style: "form" } },
1822
+ fields: { object: { style: "form" } }
1823
+ }
1824
+ },
1817
1825
  security: [{ scheme: "bearer", type: "http" }],
1818
1826
  url: "/ai/chunks/document/{document_id}",
1819
1827
  ...options
@@ -4864,6 +4872,18 @@ var patchAiConversationsById = (options) => (options.client ?? client).patch({
4864
4872
  ...options.headers
4865
4873
  }
4866
4874
  });
4875
+ var getExtractionResultsDocumentByDocumentIdHistory = (options) => (options.client ?? client).get({
4876
+ querySerializer: {
4877
+ parameters: {
4878
+ filter: { object: { style: "form" } },
4879
+ page: { object: { style: "form" } },
4880
+ fields: { object: { style: "form" } }
4881
+ }
4882
+ },
4883
+ security: [{ scheme: "bearer", type: "http" }],
4884
+ url: "/extraction/results/document/{document_id}/history",
4885
+ ...options
4886
+ });
4867
4887
  var getInvitationsMe = (options) => (options.client ?? client).get({
4868
4888
  querySerializer: {
4869
4889
  parameters: {
@@ -5366,10 +5386,33 @@ function handleApiError(error) {
5366
5386
  } else if (error?.message) {
5367
5387
  message = error.message;
5368
5388
  }
5389
+ const sensitiveHeaderPatterns = [
5390
+ "set-cookie",
5391
+ "authorization",
5392
+ "x-application-key",
5393
+ "x-api-key",
5394
+ "cookie",
5395
+ "x-forwarded-for",
5396
+ "x-real-ip",
5397
+ "proxy-authorization",
5398
+ "x-client-ip",
5399
+ "x-forwarded",
5400
+ "cf-connecting-ip",
5401
+ "x-cluster-client-ip"
5402
+ ];
5403
+ const filterSensitiveHeaders = (hdrs) => {
5404
+ if (!hdrs) return void 0;
5405
+ const entries = hdrs instanceof Headers ? Array.from(hdrs.entries()) : Object.entries(hdrs);
5406
+ const filtered = entries.filter(([key]) => {
5407
+ const lowerKey = key.toLowerCase();
5408
+ return !sensitiveHeaderPatterns.some((pattern) => lowerKey.includes(pattern));
5409
+ });
5410
+ return filtered.length > 0 ? Object.fromEntries(filtered) : void 0;
5411
+ };
5369
5412
  const errorOptions = {
5370
5413
  statusCode,
5371
5414
  requestId,
5372
- headers: headers ? headers.entries ? Object.fromEntries(headers.entries()) : Object.fromEntries(Object.entries(headers)) : void 0,
5415
+ headers: filterSensitiveHeaders(headers),
5373
5416
  body,
5374
5417
  cause: error
5375
5418
  };
@@ -5503,15 +5546,20 @@ var DEFAULT_RETRY_CONFIG = {
5503
5546
  // 1 second
5504
5547
  maxDelay: 32e3,
5505
5548
  // 32 seconds
5506
- retryableStatusCodes: [429, 500, 502, 503, 504]
5549
+ retryableStatusCodes: [429, 500, 502, 503, 504],
5550
+ totalTimeout: 3e5,
5551
+ // 5 minutes total timeout
5552
+ maxRetryAfter: 60
5553
+ // Max 60 seconds from Retry-After header
5507
5554
  };
5508
5555
  function isRetryableError(error, retryableStatusCodes) {
5509
5556
  const statusCode = error?.status || error?.statusCode || error?.response?.status;
5510
5557
  return retryableStatusCodes.includes(statusCode);
5511
5558
  }
5512
- function calculateBackoff(attempt, initialDelay, maxDelay, retryAfter) {
5513
- if (retryAfter) {
5514
- return Math.min(retryAfter * 1e3, maxDelay);
5559
+ function calculateBackoff(attempt, initialDelay, maxDelay, retryAfter, maxRetryAfter = 60) {
5560
+ if (retryAfter !== void 0 && retryAfter > 0) {
5561
+ const cappedRetryAfter = Math.min(retryAfter, maxRetryAfter);
5562
+ return Math.min(cappedRetryAfter * 1e3, maxDelay);
5515
5563
  }
5516
5564
  const exponentialDelay = initialDelay * Math.pow(2, attempt);
5517
5565
  const jitter = Math.random() * 0.3 * exponentialDelay;
@@ -5521,9 +5569,26 @@ function calculateBackoff(attempt, initialDelay, maxDelay, retryAfter) {
5521
5569
  function sleep(ms) {
5522
5570
  return new Promise((resolve) => setTimeout(resolve, ms));
5523
5571
  }
5572
+ var RetryTimeoutError = class extends Error {
5573
+ constructor(message, lastError) {
5574
+ super(message);
5575
+ this.lastError = lastError;
5576
+ this.name = "RetryTimeoutError";
5577
+ }
5578
+ };
5524
5579
  async function retryWithBackoff(fn, config = DEFAULT_RETRY_CONFIG) {
5525
5580
  let lastError;
5581
+ const startTime = Date.now();
5582
+ const totalTimeout = config.totalTimeout ?? DEFAULT_RETRY_CONFIG.totalTimeout;
5583
+ const maxRetryAfter = config.maxRetryAfter ?? DEFAULT_RETRY_CONFIG.maxRetryAfter;
5526
5584
  for (let attempt = 0; attempt <= config.maxRetries; attempt++) {
5585
+ const elapsed = Date.now() - startTime;
5586
+ if (elapsed >= totalTimeout) {
5587
+ throw new RetryTimeoutError(
5588
+ `Retry timeout exceeded after ${elapsed}ms (limit: ${totalTimeout}ms)`,
5589
+ lastError
5590
+ );
5591
+ }
5527
5592
  try {
5528
5593
  return await fn();
5529
5594
  } catch (error) {
@@ -5532,14 +5597,29 @@ async function retryWithBackoff(fn, config = DEFAULT_RETRY_CONFIG) {
5532
5597
  throw error;
5533
5598
  }
5534
5599
  const errorWithHeaders = error;
5535
- const retryAfter = errorWithHeaders?.response?.headers?.get?.("retry-after") || errorWithHeaders?.response?.headers?.["retry-after"] || errorWithHeaders?.headers?.get?.("retry-after") || errorWithHeaders?.headers?.["retry-after"];
5536
- const retryAfterSeconds = retryAfter ? parseInt(retryAfter, 10) : void 0;
5600
+ const headers = errorWithHeaders?.response?.headers || errorWithHeaders?.headers;
5601
+ const retryAfter = headers?.get?.("retry-after") || headers?.["retry-after"];
5602
+ let retryAfterSeconds;
5603
+ if (retryAfter) {
5604
+ const parsed = parseInt(String(retryAfter), 10);
5605
+ if (!isNaN(parsed) && parsed > 0 && parsed <= maxRetryAfter) {
5606
+ retryAfterSeconds = parsed;
5607
+ }
5608
+ }
5537
5609
  const delay = calculateBackoff(
5538
5610
  attempt,
5539
5611
  config.initialDelay,
5540
5612
  config.maxDelay,
5541
- retryAfterSeconds
5613
+ retryAfterSeconds,
5614
+ maxRetryAfter
5542
5615
  );
5616
+ const remainingTimeout = totalTimeout - (Date.now() - startTime);
5617
+ if (delay >= remainingTimeout) {
5618
+ throw new RetryTimeoutError(
5619
+ `Retry would exceed timeout (delay: ${delay}ms, remaining: ${remainingTimeout}ms)`,
5620
+ lastError
5621
+ );
5622
+ }
5543
5623
  await sleep(delay);
5544
5624
  }
5545
5625
  }
@@ -5573,15 +5653,35 @@ async function* paginateAll(fetcher, options = {}) {
5573
5653
  page++;
5574
5654
  }
5575
5655
  }
5656
+ var DEFAULT_LIMIT = 1e4;
5657
+ var WARNING_THRESHOLD = 1e3;
5576
5658
  async function paginateToArray(fetcher, options = {}) {
5659
+ const safeOptions = {
5660
+ pageSize: options.pageSize || 20,
5661
+ // Security: Apply default limit to prevent unbounded memory usage
5662
+ limit: options.limit ?? DEFAULT_LIMIT
5663
+ };
5664
+ if (!options.limit && typeof process !== "undefined" && process.env?.NODE_ENV !== "test") {
5665
+ console.warn(
5666
+ `[GPT Core SDK] Fetching up to ${DEFAULT_LIMIT} items. For large datasets, consider using paginateAll() with streaming instead.`
5667
+ );
5668
+ }
5669
+ if (safeOptions.limit > WARNING_THRESHOLD) {
5670
+ console.warn(
5671
+ `[GPT Core SDK] Fetching more than ${WARNING_THRESHOLD} items may consume significant memory.`
5672
+ );
5673
+ }
5577
5674
  const results = [];
5578
- for await (const item of paginateAll(fetcher, options)) {
5675
+ for await (const item of paginateAll(fetcher, safeOptions)) {
5579
5676
  results.push(item);
5580
5677
  }
5581
5678
  return results;
5582
5679
  }
5583
5680
 
5584
5681
  // src/streaming.ts
5682
+ var DEFAULT_STREAM_TIMEOUT = 3e5;
5683
+ var DEFAULT_MAX_CHUNKS = 1e4;
5684
+ var DEFAULT_MAX_BUFFER_SIZE = 10 * 1024 * 1024;
5585
5685
  async function* streamSSE(response, options = {}) {
5586
5686
  if (!response.body) {
5587
5687
  throw new Error("Response body is null");
@@ -5589,8 +5689,23 @@ async function* streamSSE(response, options = {}) {
5589
5689
  const reader = response.body.getReader();
5590
5690
  const decoder = new TextDecoder();
5591
5691
  let buffer = "";
5692
+ const timeout = options.timeout ?? DEFAULT_STREAM_TIMEOUT;
5693
+ const maxChunks = options.maxChunks ?? DEFAULT_MAX_CHUNKS;
5694
+ const maxBufferSize = options.maxBufferSize ?? DEFAULT_MAX_BUFFER_SIZE;
5695
+ const startTime = Date.now();
5696
+ let chunkCount = 0;
5697
+ let bufferSize = 0;
5592
5698
  try {
5593
5699
  while (true) {
5700
+ const elapsed = Date.now() - startTime;
5701
+ if (elapsed > timeout) {
5702
+ reader.cancel();
5703
+ throw new Error(`Stream timeout exceeded after ${elapsed}ms (limit: ${timeout}ms)`);
5704
+ }
5705
+ if (chunkCount >= maxChunks) {
5706
+ reader.cancel();
5707
+ throw new Error(`Maximum chunk limit exceeded (${maxChunks})`);
5708
+ }
5594
5709
  const { done, value } = await reader.read();
5595
5710
  if (done) {
5596
5711
  break;
@@ -5599,6 +5714,11 @@ async function* streamSSE(response, options = {}) {
5599
5714
  reader.cancel();
5600
5715
  throw new Error("Stream aborted");
5601
5716
  }
5717
+ bufferSize += value.length;
5718
+ if (bufferSize > maxBufferSize) {
5719
+ reader.cancel();
5720
+ throw new Error(`Stream buffer size exceeded (${bufferSize} bytes, limit: ${maxBufferSize})`);
5721
+ }
5602
5722
  buffer += decoder.decode(value, { stream: true });
5603
5723
  const lines = buffer.split("\n");
5604
5724
  buffer = lines.pop() || "";
@@ -5608,6 +5728,7 @@ async function* streamSSE(response, options = {}) {
5608
5728
  if (data === "[DONE]" || data.trim() === "") {
5609
5729
  continue;
5610
5730
  }
5731
+ chunkCount++;
5611
5732
  try {
5612
5733
  const parsed = JSON.parse(data);
5613
5734
  yield parsed;
@@ -5872,6 +5993,7 @@ var index_default = gptCore;
5872
5993
  PresignedUploadSchema,
5873
5994
  RateLimitError,
5874
5995
  RegisterRequestSchema,
5996
+ RetryTimeoutError,
5875
5997
  SearchRequestSchema,
5876
5998
  ServerError,
5877
5999
  ThreadCreateSchema,
@@ -5982,6 +6104,7 @@ var index_default = gptCore;
5982
6104
  getExtractionResults,
5983
6105
  getExtractionResultsById,
5984
6106
  getExtractionResultsDocumentByDocumentId,
6107
+ getExtractionResultsDocumentByDocumentIdHistory,
5985
6108
  getExtractionResultsWorkspaceByWorkspaceId,
5986
6109
  getExtractionSchemaDiscoveriesById,
5987
6110
  getFieldTemplates,
package/dist/index.mjs CHANGED
@@ -105,6 +105,7 @@ __export(sdk_gen_exports, {
105
105
  getExtractionResults: () => getExtractionResults,
106
106
  getExtractionResultsById: () => getExtractionResultsById,
107
107
  getExtractionResultsDocumentByDocumentId: () => getExtractionResultsDocumentByDocumentId,
108
+ getExtractionResultsDocumentByDocumentIdHistory: () => getExtractionResultsDocumentByDocumentIdHistory,
108
109
  getExtractionResultsWorkspaceByWorkspaceId: () => getExtractionResultsWorkspaceByWorkspaceId,
109
110
  getExtractionSchemaDiscoveriesById: () => getExtractionSchemaDiscoveriesById,
110
111
  getFieldTemplates: () => getFieldTemplates,
@@ -1348,7 +1349,12 @@ var patchApiKeysByIdRevoke = (options) => (options.client ?? client).patch({
1348
1349
  }
1349
1350
  });
1350
1351
  var getAiChunksDocumentByDocumentId = (options) => (options.client ?? client).get({
1351
- querySerializer: { parameters: { fields: { object: { style: "form" } } } },
1352
+ querySerializer: {
1353
+ parameters: {
1354
+ filter: { object: { style: "form" } },
1355
+ fields: { object: { style: "form" } }
1356
+ }
1357
+ },
1352
1358
  security: [{ scheme: "bearer", type: "http" }],
1353
1359
  url: "/ai/chunks/document/{document_id}",
1354
1360
  ...options
@@ -4399,6 +4405,18 @@ var patchAiConversationsById = (options) => (options.client ?? client).patch({
4399
4405
  ...options.headers
4400
4406
  }
4401
4407
  });
4408
+ var getExtractionResultsDocumentByDocumentIdHistory = (options) => (options.client ?? client).get({
4409
+ querySerializer: {
4410
+ parameters: {
4411
+ filter: { object: { style: "form" } },
4412
+ page: { object: { style: "form" } },
4413
+ fields: { object: { style: "form" } }
4414
+ }
4415
+ },
4416
+ security: [{ scheme: "bearer", type: "http" }],
4417
+ url: "/extraction/results/document/{document_id}/history",
4418
+ ...options
4419
+ });
4402
4420
  var getInvitationsMe = (options) => (options.client ?? client).get({
4403
4421
  querySerializer: {
4404
4422
  parameters: {
@@ -4901,10 +4919,33 @@ function handleApiError(error) {
4901
4919
  } else if (error?.message) {
4902
4920
  message = error.message;
4903
4921
  }
4922
+ const sensitiveHeaderPatterns = [
4923
+ "set-cookie",
4924
+ "authorization",
4925
+ "x-application-key",
4926
+ "x-api-key",
4927
+ "cookie",
4928
+ "x-forwarded-for",
4929
+ "x-real-ip",
4930
+ "proxy-authorization",
4931
+ "x-client-ip",
4932
+ "x-forwarded",
4933
+ "cf-connecting-ip",
4934
+ "x-cluster-client-ip"
4935
+ ];
4936
+ const filterSensitiveHeaders = (hdrs) => {
4937
+ if (!hdrs) return void 0;
4938
+ const entries = hdrs instanceof Headers ? Array.from(hdrs.entries()) : Object.entries(hdrs);
4939
+ const filtered = entries.filter(([key]) => {
4940
+ const lowerKey = key.toLowerCase();
4941
+ return !sensitiveHeaderPatterns.some((pattern) => lowerKey.includes(pattern));
4942
+ });
4943
+ return filtered.length > 0 ? Object.fromEntries(filtered) : void 0;
4944
+ };
4904
4945
  const errorOptions = {
4905
4946
  statusCode,
4906
4947
  requestId,
4907
- headers: headers ? headers.entries ? Object.fromEntries(headers.entries()) : Object.fromEntries(Object.entries(headers)) : void 0,
4948
+ headers: filterSensitiveHeaders(headers),
4908
4949
  body,
4909
4950
  cause: error
4910
4951
  };
@@ -5038,15 +5079,20 @@ var DEFAULT_RETRY_CONFIG = {
5038
5079
  // 1 second
5039
5080
  maxDelay: 32e3,
5040
5081
  // 32 seconds
5041
- retryableStatusCodes: [429, 500, 502, 503, 504]
5082
+ retryableStatusCodes: [429, 500, 502, 503, 504],
5083
+ totalTimeout: 3e5,
5084
+ // 5 minutes total timeout
5085
+ maxRetryAfter: 60
5086
+ // Max 60 seconds from Retry-After header
5042
5087
  };
5043
5088
  function isRetryableError(error, retryableStatusCodes) {
5044
5089
  const statusCode = error?.status || error?.statusCode || error?.response?.status;
5045
5090
  return retryableStatusCodes.includes(statusCode);
5046
5091
  }
5047
- function calculateBackoff(attempt, initialDelay, maxDelay, retryAfter) {
5048
- if (retryAfter) {
5049
- return Math.min(retryAfter * 1e3, maxDelay);
5092
+ function calculateBackoff(attempt, initialDelay, maxDelay, retryAfter, maxRetryAfter = 60) {
5093
+ if (retryAfter !== void 0 && retryAfter > 0) {
5094
+ const cappedRetryAfter = Math.min(retryAfter, maxRetryAfter);
5095
+ return Math.min(cappedRetryAfter * 1e3, maxDelay);
5050
5096
  }
5051
5097
  const exponentialDelay = initialDelay * Math.pow(2, attempt);
5052
5098
  const jitter = Math.random() * 0.3 * exponentialDelay;
@@ -5056,9 +5102,26 @@ function calculateBackoff(attempt, initialDelay, maxDelay, retryAfter) {
5056
5102
  function sleep(ms) {
5057
5103
  return new Promise((resolve) => setTimeout(resolve, ms));
5058
5104
  }
5105
+ var RetryTimeoutError = class extends Error {
5106
+ constructor(message, lastError) {
5107
+ super(message);
5108
+ this.lastError = lastError;
5109
+ this.name = "RetryTimeoutError";
5110
+ }
5111
+ };
5059
5112
  async function retryWithBackoff(fn, config = DEFAULT_RETRY_CONFIG) {
5060
5113
  let lastError;
5114
+ const startTime = Date.now();
5115
+ const totalTimeout = config.totalTimeout ?? DEFAULT_RETRY_CONFIG.totalTimeout;
5116
+ const maxRetryAfter = config.maxRetryAfter ?? DEFAULT_RETRY_CONFIG.maxRetryAfter;
5061
5117
  for (let attempt = 0; attempt <= config.maxRetries; attempt++) {
5118
+ const elapsed = Date.now() - startTime;
5119
+ if (elapsed >= totalTimeout) {
5120
+ throw new RetryTimeoutError(
5121
+ `Retry timeout exceeded after ${elapsed}ms (limit: ${totalTimeout}ms)`,
5122
+ lastError
5123
+ );
5124
+ }
5062
5125
  try {
5063
5126
  return await fn();
5064
5127
  } catch (error) {
@@ -5067,14 +5130,29 @@ async function retryWithBackoff(fn, config = DEFAULT_RETRY_CONFIG) {
5067
5130
  throw error;
5068
5131
  }
5069
5132
  const errorWithHeaders = error;
5070
- const retryAfter = errorWithHeaders?.response?.headers?.get?.("retry-after") || errorWithHeaders?.response?.headers?.["retry-after"] || errorWithHeaders?.headers?.get?.("retry-after") || errorWithHeaders?.headers?.["retry-after"];
5071
- const retryAfterSeconds = retryAfter ? parseInt(retryAfter, 10) : void 0;
5133
+ const headers = errorWithHeaders?.response?.headers || errorWithHeaders?.headers;
5134
+ const retryAfter = headers?.get?.("retry-after") || headers?.["retry-after"];
5135
+ let retryAfterSeconds;
5136
+ if (retryAfter) {
5137
+ const parsed = parseInt(String(retryAfter), 10);
5138
+ if (!isNaN(parsed) && parsed > 0 && parsed <= maxRetryAfter) {
5139
+ retryAfterSeconds = parsed;
5140
+ }
5141
+ }
5072
5142
  const delay = calculateBackoff(
5073
5143
  attempt,
5074
5144
  config.initialDelay,
5075
5145
  config.maxDelay,
5076
- retryAfterSeconds
5146
+ retryAfterSeconds,
5147
+ maxRetryAfter
5077
5148
  );
5149
+ const remainingTimeout = totalTimeout - (Date.now() - startTime);
5150
+ if (delay >= remainingTimeout) {
5151
+ throw new RetryTimeoutError(
5152
+ `Retry would exceed timeout (delay: ${delay}ms, remaining: ${remainingTimeout}ms)`,
5153
+ lastError
5154
+ );
5155
+ }
5078
5156
  await sleep(delay);
5079
5157
  }
5080
5158
  }
@@ -5108,15 +5186,35 @@ async function* paginateAll(fetcher, options = {}) {
5108
5186
  page++;
5109
5187
  }
5110
5188
  }
5189
+ var DEFAULT_LIMIT = 1e4;
5190
+ var WARNING_THRESHOLD = 1e3;
5111
5191
  async function paginateToArray(fetcher, options = {}) {
5192
+ const safeOptions = {
5193
+ pageSize: options.pageSize || 20,
5194
+ // Security: Apply default limit to prevent unbounded memory usage
5195
+ limit: options.limit ?? DEFAULT_LIMIT
5196
+ };
5197
+ if (!options.limit && typeof process !== "undefined" && process.env?.NODE_ENV !== "test") {
5198
+ console.warn(
5199
+ `[GPT Core SDK] Fetching up to ${DEFAULT_LIMIT} items. For large datasets, consider using paginateAll() with streaming instead.`
5200
+ );
5201
+ }
5202
+ if (safeOptions.limit > WARNING_THRESHOLD) {
5203
+ console.warn(
5204
+ `[GPT Core SDK] Fetching more than ${WARNING_THRESHOLD} items may consume significant memory.`
5205
+ );
5206
+ }
5112
5207
  const results = [];
5113
- for await (const item of paginateAll(fetcher, options)) {
5208
+ for await (const item of paginateAll(fetcher, safeOptions)) {
5114
5209
  results.push(item);
5115
5210
  }
5116
5211
  return results;
5117
5212
  }
5118
5213
 
5119
5214
  // src/streaming.ts
5215
+ var DEFAULT_STREAM_TIMEOUT = 3e5;
5216
+ var DEFAULT_MAX_CHUNKS = 1e4;
5217
+ var DEFAULT_MAX_BUFFER_SIZE = 10 * 1024 * 1024;
5120
5218
  async function* streamSSE(response, options = {}) {
5121
5219
  if (!response.body) {
5122
5220
  throw new Error("Response body is null");
@@ -5124,8 +5222,23 @@ async function* streamSSE(response, options = {}) {
5124
5222
  const reader = response.body.getReader();
5125
5223
  const decoder = new TextDecoder();
5126
5224
  let buffer = "";
5225
+ const timeout = options.timeout ?? DEFAULT_STREAM_TIMEOUT;
5226
+ const maxChunks = options.maxChunks ?? DEFAULT_MAX_CHUNKS;
5227
+ const maxBufferSize = options.maxBufferSize ?? DEFAULT_MAX_BUFFER_SIZE;
5228
+ const startTime = Date.now();
5229
+ let chunkCount = 0;
5230
+ let bufferSize = 0;
5127
5231
  try {
5128
5232
  while (true) {
5233
+ const elapsed = Date.now() - startTime;
5234
+ if (elapsed > timeout) {
5235
+ reader.cancel();
5236
+ throw new Error(`Stream timeout exceeded after ${elapsed}ms (limit: ${timeout}ms)`);
5237
+ }
5238
+ if (chunkCount >= maxChunks) {
5239
+ reader.cancel();
5240
+ throw new Error(`Maximum chunk limit exceeded (${maxChunks})`);
5241
+ }
5129
5242
  const { done, value } = await reader.read();
5130
5243
  if (done) {
5131
5244
  break;
@@ -5134,6 +5247,11 @@ async function* streamSSE(response, options = {}) {
5134
5247
  reader.cancel();
5135
5248
  throw new Error("Stream aborted");
5136
5249
  }
5250
+ bufferSize += value.length;
5251
+ if (bufferSize > maxBufferSize) {
5252
+ reader.cancel();
5253
+ throw new Error(`Stream buffer size exceeded (${bufferSize} bytes, limit: ${maxBufferSize})`);
5254
+ }
5137
5255
  buffer += decoder.decode(value, { stream: true });
5138
5256
  const lines = buffer.split("\n");
5139
5257
  buffer = lines.pop() || "";
@@ -5143,6 +5261,7 @@ async function* streamSSE(response, options = {}) {
5143
5261
  if (data === "[DONE]" || data.trim() === "") {
5144
5262
  continue;
5145
5263
  }
5264
+ chunkCount++;
5146
5265
  try {
5147
5266
  const parsed = JSON.parse(data);
5148
5267
  yield parsed;
@@ -5406,6 +5525,7 @@ export {
5406
5525
  PresignedUploadSchema,
5407
5526
  RateLimitError,
5408
5527
  RegisterRequestSchema,
5528
+ RetryTimeoutError,
5409
5529
  SearchRequestSchema,
5410
5530
  ServerError,
5411
5531
  ThreadCreateSchema,
@@ -5517,6 +5637,7 @@ export {
5517
5637
  getExtractionResults,
5518
5638
  getExtractionResultsById,
5519
5639
  getExtractionResultsDocumentByDocumentId,
5640
+ getExtractionResultsDocumentByDocumentIdHistory,
5520
5641
  getExtractionResultsWorkspaceByWorkspaceId,
5521
5642
  getExtractionSchemaDiscoveriesById,
5522
5643
  getFieldTemplates,
package/llms.txt CHANGED
@@ -265,6 +265,7 @@ client.setConfig({
265
265
  - `getExtractionResults()` - List results
266
266
  - `getExtractionResultsById()` - Get results
267
267
  - `getExtractionResultsDocumentByDocumentId()` - Get document
268
+ - `getExtractionResultsDocumentByDocumentIdHistory()` - Get history
268
269
  - `getExtractionResultsWorkspaceByWorkspaceId()` - Get workspace
269
270
  - `patchExtractionResultsById()` - Update results
270
271
  - `patchExtractionResultsByIdRegenerate()` - Update regenerate
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@gpt-core/client",
3
- "version": "0.10.12",
3
+ "version": "0.10.20",
4
4
  "description": "TypeScript SDK for GPT Core Client API - Document extraction, AI agents, and workspace management",
5
5
  "main": "dist/index.js",
6
6
  "module": "dist/index.mjs",
@@ -52,15 +52,6 @@
52
52
  "publishConfig": {
53
53
  "access": "public"
54
54
  },
55
- "scripts": {
56
- "generate": "openapi-ts",
57
- "typecheck": "tsc --noEmit",
58
- "build": "npm run typecheck && tsup src/index.ts --format cjs,esm --dts",
59
- "test": "vitest run",
60
- "test:watch": "vitest",
61
- "test:ui": "vitest --ui",
62
- "test:coverage": "vitest run --coverage"
63
- },
64
55
  "dependencies": {
65
56
  "eventsource-parser": "^3.0.6",
66
57
  "zod": "^3.25.76"
@@ -72,5 +63,14 @@
72
63
  "tsup": "^8.5.1",
73
64
  "typescript": "^5.9.3",
74
65
  "vitest": "^4.0.15"
66
+ },
67
+ "scripts": {
68
+ "generate": "bunx openapi-ts",
69
+ "typecheck": "bunx tsc --noEmit",
70
+ "build": "bun run typecheck && bunx tsup src/index.ts --format cjs,esm --dts",
71
+ "test": "bunx vitest run",
72
+ "test:watch": "bunx vitest",
73
+ "test:ui": "bunx vitest --ui",
74
+ "test:coverage": "bunx vitest run --coverage"
75
75
  }
76
- }
76
+ }