seacloud-sdk 0.12.0 → 0.12.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.d.ts CHANGED
@@ -12420,7 +12420,7 @@ declare function llmChatCompletions(params: LlmChatCompletionsParams & {
12420
12420
  * - For tool calls (image/video generation), streaming is RECOMMENDED
12421
12421
  *
12422
12422
  * 4. AUTHENTICATION:
12423
- * - Requires 'X-Project' header (configured via initSeacloud({ xProject: 'SeaArt' }))
12423
+ * - Requires 'X-Project' header (configured via initSeacloud({ xProject: 'SeaVerse' }))
12424
12424
  * - Uses Bearer token authentication
12425
12425
  *
12426
12426
  * 5. SESSION MANAGEMENT:
package/dist/index.js CHANGED
@@ -352,24 +352,80 @@ function isTaskComplete(status) {
352
352
  function sleep(ms) {
353
353
  return new Promise((resolve) => setTimeout(resolve, ms));
354
354
  }
355
+ function isNetworkError(error) {
356
+ if (error instanceof SeacloudError) {
357
+ const statusCode = error.statusCode;
358
+ if (!statusCode) return false;
359
+ const networkStatusCodes = [
360
+ 408,
361
+ // Request Timeout
362
+ 500,
363
+ // Internal Server Error
364
+ 502,
365
+ // Bad Gateway
366
+ 503,
367
+ // Service Unavailable
368
+ 504
369
+ // Gateway Timeout
370
+ ];
371
+ return networkStatusCodes.includes(statusCode);
372
+ }
373
+ if (error instanceof Error) {
374
+ const errorCode = error.code;
375
+ const networkErrorCodes = [
376
+ "ETIMEDOUT",
377
+ "ECONNRESET",
378
+ "ECONNREFUSED",
379
+ "ENOTFOUND",
380
+ "EAI_AGAIN",
381
+ "ENETUNREACH",
382
+ "EHOSTUNREACH"
383
+ ];
384
+ if (errorCode && networkErrorCodes.includes(errorCode)) {
385
+ return true;
386
+ }
387
+ }
388
+ return false;
389
+ }
355
390
  async function pollTaskUntilComplete(client, endpoint, taskId, options = {}) {
356
391
  const opts = { ...DEFAULT_POLLING_OPTIONS, ...options };
392
+ let consecutiveNetworkErrors = 0;
393
+ const MAX_CONSECUTIVE_NETWORK_ERRORS = 3;
357
394
  for (let attempt = 1; attempt <= opts.maxAttempts; attempt++) {
358
- const result = await client.getTaskStatus(endpoint, taskId);
359
- opts.onProgress(attempt, result.status);
360
- if (isTaskComplete(result.status)) {
361
- if (result.status === "failed") {
362
- const errorMsg = result.error?.message || "Task failed without error message";
363
- throw new SeacloudError(
364
- `Task failed: ${errorMsg}`,
365
- void 0,
366
- result.error
367
- );
395
+ try {
396
+ const result = await client.getTaskStatus(endpoint, taskId);
397
+ consecutiveNetworkErrors = 0;
398
+ opts.onProgress(attempt, result.status);
399
+ if (isTaskComplete(result.status)) {
400
+ if (result.status === "failed") {
401
+ const errorMsg = result.error?.message || "Task failed without error message";
402
+ throw new SeacloudError(
403
+ `Task failed: ${errorMsg}`,
404
+ void 0,
405
+ result.error
406
+ );
407
+ }
408
+ return result;
409
+ }
410
+ if (attempt < opts.maxAttempts) {
411
+ await sleep(opts.intervalMs);
412
+ }
413
+ } catch (error) {
414
+ if (isNetworkError(error)) {
415
+ consecutiveNetworkErrors++;
416
+ if (consecutiveNetworkErrors >= MAX_CONSECUTIVE_NETWORK_ERRORS) {
417
+ throw new SeacloudError(
418
+ `Task polling failed: encountered ${MAX_CONSECUTIVE_NETWORK_ERRORS} consecutive network errors. Last error: ${error.message}`,
419
+ error.statusCode,
420
+ error
421
+ );
422
+ }
423
+ if (attempt < opts.maxAttempts) {
424
+ await sleep(opts.intervalMs);
425
+ }
426
+ } else {
427
+ throw error;
368
428
  }
369
- return result;
370
- }
371
- if (attempt < opts.maxAttempts) {
372
- await sleep(opts.intervalMs);
373
429
  }
374
430
  }
375
431
  throw new SeacloudError(
@@ -1598,10 +1654,17 @@ async function googleGeminiImage(params) {
1598
1654
  pollingOptions
1599
1655
  );
1600
1656
  const resources = [];
1657
+ let firstTextResource = null;
1601
1658
  if (result.output) {
1602
1659
  for (const item of result.output) {
1603
1660
  if (item.content) {
1604
1661
  for (const resource of item.content) {
1662
+ if (resource.type === "text") {
1663
+ if (!firstTextResource) {
1664
+ firstTextResource = resource;
1665
+ }
1666
+ continue;
1667
+ }
1605
1668
  validateResourceUrl(resource, "image");
1606
1669
  resources.push({
1607
1670
  type: resource.type || "unknown",
@@ -1614,6 +1677,10 @@ async function googleGeminiImage(params) {
1614
1677
  }
1615
1678
  }
1616
1679
  }
1680
+ if (resources.length === 0) {
1681
+ const errorResource = firstTextResource || { type: "text", url: "" };
1682
+ validateResourceUrl(errorResource, "image");
1683
+ }
1617
1684
  return resources;
1618
1685
  }
1619
1686