@ai-sdk/gateway 4.0.43 → 4.0.44

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/CHANGELOG.md CHANGED
@@ -1,5 +1,20 @@
1
1
  # @ai-sdk/gateway
2
2
 
3
+ ## 4.0.44
4
+
5
+ ### Patch Changes
6
+
7
+ - 89080c8: feat (provider/gateway): support the async video operation flow (doStart/doStatus) on the v4 video model
8
+ - 89080c8: fix (ai/gateway): make retried `doStart` calls idempotent
9
+
10
+ `generateVideo` retries `doStart`, which creates a billable generation, so a
11
+ retry after a lost response could start a second one. It now mints one
12
+ idempotency token per logical start — outside the retry closure — and forwards it
13
+ as an `idempotency-key` header, so a provider that deduplicates (the Vercel AI
14
+ Gateway does) sees the same key on every attempt. `GatewayVideoModel` simply
15
+ forwards the caller's headers rather than inferring retry identity from an
16
+ options object, which would collide across unrelated calls.
17
+
3
18
  ## 4.0.43
4
19
 
5
20
  ### Patch Changes
package/dist/index.js CHANGED
@@ -63,7 +63,7 @@ function decodeSubprotocolValue(value) {
63
63
  // src/gateway-provider.ts
64
64
  import {
65
65
  createJsonErrorResponseHandler as createJsonErrorResponseHandler11,
66
- createJsonResponseHandler as createJsonResponseHandler10,
66
+ createJsonResponseHandler as createJsonResponseHandler11,
67
67
  loadOptionalSetting,
68
68
  postJsonToApi as postJsonToApi8,
69
69
  withoutTrailingSlash,
@@ -1413,6 +1413,7 @@ import {
1413
1413
  combineHeaders as combineHeaders4,
1414
1414
  convertUint8ArrayToBase64 as convertUint8ArrayToBase642,
1415
1415
  createJsonErrorResponseHandler as createJsonErrorResponseHandler7,
1416
+ createJsonResponseHandler as createJsonResponseHandler7,
1416
1417
  parseJsonEventStream,
1417
1418
  postJsonToApi as postJsonToApi4,
1418
1419
  resolve as resolve7
@@ -1429,23 +1430,9 @@ var GatewayVideoModel = class {
1429
1430
  get provider() {
1430
1431
  return this.config.provider;
1431
1432
  }
1432
- async doGenerate({
1433
- prompt,
1434
- n,
1435
- aspectRatio,
1436
- resolution,
1437
- duration,
1438
- fps,
1439
- seed,
1440
- generateAudio,
1441
- image,
1442
- frameImages,
1443
- inputReferences,
1444
- providerOptions,
1445
- headers,
1446
- abortSignal
1447
- }) {
1448
- var _a11;
1433
+ async doGenerate(options) {
1434
+ var _a11, _b11;
1435
+ const { headers, abortSignal } = options;
1449
1436
  const resolvedHeaders = this.config.headers ? await resolve7(this.config.headers) : void 0;
1450
1437
  try {
1451
1438
  const { responseHeaders, value: responseBody } = await postJsonToApi4({
@@ -1457,29 +1444,7 @@ var GatewayVideoModel = class {
1457
1444
  await resolve7(this.config.o11yHeaders),
1458
1445
  { accept: "text/event-stream" }
1459
1446
  ),
1460
- body: {
1461
- prompt,
1462
- n,
1463
- ...aspectRatio && { aspectRatio },
1464
- ...resolution && { resolution },
1465
- ...duration && { duration },
1466
- ...fps && { fps },
1467
- ...seed && { seed },
1468
- ...generateAudio !== void 0 && { generateAudio },
1469
- ...providerOptions && { providerOptions },
1470
- ...image && { image: maybeEncodeVideoFile(image) },
1471
- ...frameImages && {
1472
- frameImages: frameImages.map((frame) => ({
1473
- ...frame,
1474
- image: maybeEncodeVideoFile(frame.image)
1475
- }))
1476
- },
1477
- ...inputReferences && {
1478
- inputReferences: inputReferences.map(
1479
- (reference) => maybeEncodeVideoFile(reference)
1480
- )
1481
- }
1482
- },
1447
+ body: this.buildRequestBody(options),
1483
1448
  successfulResponseHandler: async ({
1484
1449
  response,
1485
1450
  url,
@@ -1554,7 +1519,7 @@ var GatewayVideoModel = class {
1554
1519
  return {
1555
1520
  videos: responseBody.videos,
1556
1521
  warnings: (_a11 = responseBody.warnings) != null ? _a11 : [],
1557
- providerMetadata: responseBody.providerMetadata,
1522
+ providerMetadata: (_b11 = responseBody.providerMetadata) != null ? _b11 : void 0,
1558
1523
  response: {
1559
1524
  timestamp: /* @__PURE__ */ new Date(),
1560
1525
  modelId: this.modelId,
@@ -1568,9 +1533,178 @@ var GatewayVideoModel = class {
1568
1533
  );
1569
1534
  }
1570
1535
  }
1536
+ // `handleWebhookOption` is intentionally NOT implemented. The Gateway's
1537
+ // async video jobs are polling-first: it does not expose a provider->SDK
1538
+ // webhook completion channel. If this method were present, `generateVideo`
1539
+ // would forward a webhook URL and await a notification that never arrives.
1540
+ // `doStart` still forwards the spec's `webhookUrl` — as the Gateway's
1541
+ // `callbackUrl` wire field (its completion-webhook contract; unknown body
1542
+ // keys are stripped server-side). Enabling webhooks later requires adding
1543
+ // `handleWebhookOption` here plus handling the Gateway's HMAC-signed
1544
+ // delivery format; the wire field is already the right one.
1545
+ async doStart(options) {
1546
+ var _a11, _b11;
1547
+ const { headers, abortSignal, webhookUrl } = options;
1548
+ const resolvedHeaders = this.config.headers ? await resolve7(this.config.headers) : void 0;
1549
+ try {
1550
+ const { responseHeaders, value: responseBody } = await postJsonToApi4({
1551
+ url: this.getStartUrl(),
1552
+ headers: combineHeaders4(
1553
+ resolvedHeaders,
1554
+ headers != null ? headers : {},
1555
+ this.getModelConfigHeaders(),
1556
+ await resolve7(this.config.o11yHeaders)
1557
+ ),
1558
+ body: {
1559
+ ...this.buildRequestBody(options),
1560
+ // The spec option is `webhookUrl`; the Gateway's wire contract for a
1561
+ // completion webhook is `callbackUrl`.
1562
+ ...webhookUrl && { callbackUrl: webhookUrl }
1563
+ },
1564
+ successfulResponseHandler: createJsonResponseHandler7(
1565
+ gatewayVideoStartResponseSchema
1566
+ ),
1567
+ failedResponseHandler: createJsonErrorResponseHandler7({
1568
+ errorSchema: z11.any(),
1569
+ errorToMessage: (data) => data
1570
+ }),
1571
+ ...abortSignal && { abortSignal },
1572
+ fetch: this.config.fetch
1573
+ });
1574
+ return {
1575
+ operation: responseBody.operation,
1576
+ warnings: (_a11 = responseBody.warnings) != null ? _a11 : [],
1577
+ providerMetadata: (_b11 = responseBody.providerMetadata) != null ? _b11 : void 0,
1578
+ response: {
1579
+ timestamp: /* @__PURE__ */ new Date(),
1580
+ modelId: this.modelId,
1581
+ headers: responseHeaders
1582
+ }
1583
+ };
1584
+ } catch (error) {
1585
+ throw await asGatewayError(
1586
+ error,
1587
+ await parseAuthMethod(resolvedHeaders != null ? resolvedHeaders : {})
1588
+ );
1589
+ }
1590
+ }
1591
+ async doStatus({
1592
+ operation,
1593
+ abortSignal,
1594
+ headers
1595
+ }) {
1596
+ var _a11, _b11, _c, _d, _e, _f;
1597
+ const resolvedHeaders = this.config.headers ? await resolve7(this.config.headers) : void 0;
1598
+ try {
1599
+ const { responseHeaders, value: responseBody } = await postJsonToApi4({
1600
+ url: this.getStatusUrl(),
1601
+ headers: combineHeaders4(
1602
+ resolvedHeaders,
1603
+ headers != null ? headers : {},
1604
+ this.getModelConfigHeaders(),
1605
+ await resolve7(this.config.o11yHeaders)
1606
+ ),
1607
+ body: { operation },
1608
+ successfulResponseHandler: createJsonResponseHandler7(
1609
+ gatewayVideoStatusResponseSchema
1610
+ ),
1611
+ failedResponseHandler: createJsonErrorResponseHandler7({
1612
+ errorSchema: z11.any(),
1613
+ errorToMessage: (data) => data
1614
+ }),
1615
+ ...abortSignal && { abortSignal },
1616
+ fetch: this.config.fetch
1617
+ });
1618
+ const response = {
1619
+ timestamp: /* @__PURE__ */ new Date(),
1620
+ modelId: this.modelId,
1621
+ headers: responseHeaders
1622
+ };
1623
+ if (responseBody.status === "completed") {
1624
+ return {
1625
+ status: "completed",
1626
+ videos: responseBody.videos,
1627
+ warnings: (_a11 = responseBody.warnings) != null ? _a11 : [],
1628
+ providerMetadata: (_b11 = responseBody.providerMetadata) != null ? _b11 : void 0,
1629
+ response
1630
+ };
1631
+ }
1632
+ if (responseBody.status === "error") {
1633
+ return {
1634
+ status: "error",
1635
+ error: responseBody.error,
1636
+ providerMetadata: (_c = responseBody.providerMetadata) != null ? _c : void 0,
1637
+ response
1638
+ };
1639
+ }
1640
+ if (responseBody.status === "cancelled") {
1641
+ return {
1642
+ status: "error",
1643
+ error: "Video generation was cancelled.",
1644
+ providerMetadata: (_d = responseBody.providerMetadata) != null ? _d : void 0,
1645
+ response
1646
+ };
1647
+ }
1648
+ return {
1649
+ status: "pending",
1650
+ warnings: (_e = responseBody.warnings) != null ? _e : [],
1651
+ providerMetadata: (_f = responseBody.providerMetadata) != null ? _f : void 0,
1652
+ response
1653
+ };
1654
+ } catch (error) {
1655
+ throw await asGatewayError(
1656
+ error,
1657
+ await parseAuthMethod(resolvedHeaders != null ? resolvedHeaders : {})
1658
+ );
1659
+ }
1660
+ }
1661
+ buildRequestBody({
1662
+ prompt,
1663
+ n,
1664
+ aspectRatio,
1665
+ resolution,
1666
+ duration,
1667
+ fps,
1668
+ seed,
1669
+ generateAudio,
1670
+ image,
1671
+ frameImages,
1672
+ inputReferences,
1673
+ providerOptions
1674
+ }) {
1675
+ return {
1676
+ prompt,
1677
+ n,
1678
+ ...aspectRatio && { aspectRatio },
1679
+ ...resolution && { resolution },
1680
+ ...duration && { duration },
1681
+ ...fps && { fps },
1682
+ ...seed && { seed },
1683
+ ...generateAudio !== void 0 && { generateAudio },
1684
+ ...providerOptions && { providerOptions },
1685
+ ...image && { image: maybeEncodeVideoFile(image) },
1686
+ ...frameImages && {
1687
+ frameImages: frameImages.map((frame) => ({
1688
+ ...frame,
1689
+ image: maybeEncodeVideoFile(frame.image)
1690
+ }))
1691
+ },
1692
+ ...inputReferences && {
1693
+ inputReferences: inputReferences.map(
1694
+ (reference) => maybeEncodeVideoFile(reference)
1695
+ )
1696
+ }
1697
+ };
1698
+ }
1571
1699
  getUrl() {
1572
1700
  return `${this.config.baseURL}/video-model`;
1573
1701
  }
1702
+ getStartUrl() {
1703
+ return `${this.config.baseURL}/video-model/start`;
1704
+ }
1705
+ getStatusUrl() {
1706
+ return `${this.config.baseURL}/video-model/status`;
1707
+ }
1574
1708
  getModelConfigHeaders() {
1575
1709
  return {
1576
1710
  "ai-video-model-specification-version": "4",
@@ -1638,12 +1772,39 @@ var gatewayVideoEventSchema = z11.discriminatedUnion("type", [
1638
1772
  param: z11.unknown().nullable()
1639
1773
  })
1640
1774
  ]);
1775
+ var gatewayVideoStartResponseSchema = z11.object({
1776
+ operation: z11.unknown(),
1777
+ warnings: z11.array(gatewayVideoWarningSchema).nullish(),
1778
+ providerMetadata: z11.record(z11.string(), providerMetadataEntrySchema2).nullish()
1779
+ });
1780
+ var gatewayVideoStatusResponseSchema = z11.discriminatedUnion("status", [
1781
+ z11.object({
1782
+ status: z11.literal("pending"),
1783
+ warnings: z11.array(gatewayVideoWarningSchema).nullish(),
1784
+ providerMetadata: z11.record(z11.string(), providerMetadataEntrySchema2).nullish()
1785
+ }),
1786
+ z11.object({
1787
+ status: z11.literal("completed"),
1788
+ videos: z11.array(gatewayVideoDataSchema),
1789
+ warnings: z11.array(gatewayVideoWarningSchema).nullish(),
1790
+ providerMetadata: z11.record(z11.string(), providerMetadataEntrySchema2).nullish()
1791
+ }),
1792
+ z11.object({
1793
+ status: z11.literal("error"),
1794
+ error: z11.string(),
1795
+ providerMetadata: z11.record(z11.string(), providerMetadataEntrySchema2).nullish()
1796
+ }),
1797
+ z11.object({
1798
+ status: z11.literal("cancelled"),
1799
+ providerMetadata: z11.record(z11.string(), providerMetadataEntrySchema2).nullish()
1800
+ })
1801
+ ]);
1641
1802
 
1642
1803
  // src/gateway-reranking-model.ts
1643
1804
  import {
1644
1805
  combineHeaders as combineHeaders5,
1645
1806
  createJsonErrorResponseHandler as createJsonErrorResponseHandler8,
1646
- createJsonResponseHandler as createJsonResponseHandler7,
1807
+ createJsonResponseHandler as createJsonResponseHandler8,
1647
1808
  lazySchema as lazySchema9,
1648
1809
  postJsonToApi as postJsonToApi5,
1649
1810
  resolve as resolve8,
@@ -1688,7 +1849,7 @@ var GatewayRerankingModel = class {
1688
1849
  ...topN != null ? { topN } : {},
1689
1850
  ...providerOptions ? { providerOptions } : {}
1690
1851
  },
1691
- successfulResponseHandler: createJsonResponseHandler7(
1852
+ successfulResponseHandler: createJsonResponseHandler8(
1692
1853
  gatewayRerankingResponseSchema
1693
1854
  ),
1694
1855
  failedResponseHandler: createJsonErrorResponseHandler8({
@@ -1761,7 +1922,7 @@ var gatewayRerankingResponseSchema = lazySchema9(
1761
1922
  import {
1762
1923
  combineHeaders as combineHeaders6,
1763
1924
  createJsonErrorResponseHandler as createJsonErrorResponseHandler9,
1764
- createJsonResponseHandler as createJsonResponseHandler8,
1925
+ createJsonResponseHandler as createJsonResponseHandler9,
1765
1926
  postJsonToApi as postJsonToApi6,
1766
1927
  resolve as resolve9
1767
1928
  } from "@ai-sdk/provider-utils";
@@ -1810,7 +1971,7 @@ var GatewaySpeechModel = class {
1810
1971
  ...language && { language },
1811
1972
  ...providerOptions && { providerOptions }
1812
1973
  },
1813
- successfulResponseHandler: createJsonResponseHandler8(
1974
+ successfulResponseHandler: createJsonResponseHandler9(
1814
1975
  gatewaySpeechResponseSchema
1815
1976
  ),
1816
1977
  failedResponseHandler: createJsonErrorResponseHandler9({
@@ -1885,7 +2046,7 @@ import {
1885
2046
  convertBase64ToUint8Array,
1886
2047
  convertUint8ArrayToBase64 as convertUint8ArrayToBase643,
1887
2048
  createJsonErrorResponseHandler as createJsonErrorResponseHandler10,
1888
- createJsonResponseHandler as createJsonResponseHandler9,
2049
+ createJsonResponseHandler as createJsonResponseHandler10,
1889
2050
  connectToWebSocket,
1890
2051
  normalizeHeaders,
1891
2052
  experimental_parseTranscriptionStreamPart as parseTranscriptionStreamPart,
@@ -1932,7 +2093,7 @@ var GatewayTranscriptionModel = class {
1932
2093
  mediaType,
1933
2094
  ...providerOptions && { providerOptions }
1934
2095
  },
1935
- successfulResponseHandler: createJsonResponseHandler9(
2096
+ successfulResponseHandler: createJsonResponseHandler10(
1936
2097
  gatewayTranscriptionResponseSchema
1937
2098
  ),
1938
2099
  failedResponseHandler: createJsonErrorResponseHandler10({
@@ -2631,7 +2792,7 @@ async function getVercelRequestId() {
2631
2792
  }
2632
2793
 
2633
2794
  // src/version.ts
2634
- var VERSION = true ? "4.0.43" : "0.0.0-test";
2795
+ var VERSION = true ? "4.0.44" : "0.0.0-test";
2635
2796
 
2636
2797
  // src/gateway-provider.ts
2637
2798
  var AI_GATEWAY_PROTOCOL_VERSION = "0.0.1";
@@ -2696,7 +2857,7 @@ function createGateway(options = {}) {
2696
2857
  expiresIn: params.expiresAfterSeconds
2697
2858
  }
2698
2859
  },
2699
- successfulResponseHandler: createJsonResponseHandler10(
2860
+ successfulResponseHandler: createJsonResponseHandler11(
2700
2861
  gatewayClientSecretResponseSchema
2701
2862
  ),
2702
2863
  failedResponseHandler: createJsonErrorResponseHandler11({