@mastra/core 0.19.0 → 0.19.1-alpha.0

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.
Files changed (164) hide show
  1. package/CHANGELOG.md +8 -0
  2. package/dist/agent/agent.d.ts +2 -2
  3. package/dist/agent/agent.d.ts.map +1 -1
  4. package/dist/agent/index.cjs +11 -11
  5. package/dist/agent/index.js +2 -2
  6. package/dist/agent/input-processor/index.cjs +6 -6
  7. package/dist/agent/input-processor/index.js +1 -1
  8. package/dist/ai-tracing/index.cjs +32 -32
  9. package/dist/ai-tracing/index.js +1 -1
  10. package/dist/cache/index.cjs +3 -3
  11. package/dist/cache/index.js +1 -1
  12. package/dist/{chunk-4VNAMG7K.cjs → chunk-2C5AQMP5.cjs} +6 -6
  13. package/dist/{chunk-4VNAMG7K.cjs.map → chunk-2C5AQMP5.cjs.map} +1 -1
  14. package/dist/{chunk-JKLLXBOY.js → chunk-2EMOWXLL.js} +9 -9
  15. package/dist/{chunk-JKLLXBOY.js.map → chunk-2EMOWXLL.js.map} +1 -1
  16. package/dist/{chunk-EPMJYNEK.cjs → chunk-2F4RLQ5V.cjs} +4 -4
  17. package/dist/{chunk-EPMJYNEK.cjs.map → chunk-2F4RLQ5V.cjs.map} +1 -1
  18. package/dist/{chunk-HNBU4PI7.cjs → chunk-3I3NRXSD.cjs} +4 -4
  19. package/dist/{chunk-HNBU4PI7.cjs.map → chunk-3I3NRXSD.cjs.map} +1 -1
  20. package/dist/{chunk-SQQMX4VC.cjs → chunk-4PRV2Y55.cjs} +6 -6
  21. package/dist/{chunk-SQQMX4VC.cjs.map → chunk-4PRV2Y55.cjs.map} +1 -1
  22. package/dist/{chunk-7E4ESNZS.cjs → chunk-576KDLXN.cjs} +5 -5
  23. package/dist/{chunk-7E4ESNZS.cjs.map → chunk-576KDLXN.cjs.map} +1 -1
  24. package/dist/{chunk-PG6ZNDSR.cjs → chunk-57UPIDGK.cjs} +19 -19
  25. package/dist/{chunk-PG6ZNDSR.cjs.map → chunk-57UPIDGK.cjs.map} +1 -1
  26. package/dist/{chunk-5BQOHHCI.js → chunk-5QUE7HZF.js} +4 -4
  27. package/dist/{chunk-5BQOHHCI.js.map → chunk-5QUE7HZF.js.map} +1 -1
  28. package/dist/{chunk-CQ73JM2N.cjs → chunk-62I4SVWU.cjs} +10 -10
  29. package/dist/{chunk-CQ73JM2N.cjs.map → chunk-62I4SVWU.cjs.map} +1 -1
  30. package/dist/{chunk-COC64XPP.js → chunk-7CJKBCDL.js} +8 -8
  31. package/dist/{chunk-COC64XPP.js.map → chunk-7CJKBCDL.js.map} +1 -1
  32. package/dist/chunk-7J5DS33F.js +3 -0
  33. package/dist/chunk-7J5DS33F.js.map +1 -0
  34. package/dist/{chunk-RAXBZZKS.js → chunk-A7REAXWA.js} +3 -3
  35. package/dist/{chunk-RAXBZZKS.js.map → chunk-A7REAXWA.js.map} +1 -1
  36. package/dist/{chunk-DRVSEV5Y.cjs → chunk-BBTR6DPH.cjs} +8 -8
  37. package/dist/{chunk-DRVSEV5Y.cjs.map → chunk-BBTR6DPH.cjs.map} +1 -1
  38. package/dist/{chunk-FV3SA5TI.js → chunk-BMBWTBCL.js} +3 -3
  39. package/dist/{chunk-FV3SA5TI.js.map → chunk-BMBWTBCL.js.map} +1 -1
  40. package/dist/{chunk-NHJVMZIL.cjs → chunk-CC4KO56Z.cjs} +19 -19
  41. package/dist/{chunk-NHJVMZIL.cjs.map → chunk-CC4KO56Z.cjs.map} +1 -1
  42. package/dist/{chunk-N4PK4MOG.js → chunk-D2ZPF2AK.js} +4 -4
  43. package/dist/{chunk-N4PK4MOG.js.map → chunk-D2ZPF2AK.js.map} +1 -1
  44. package/dist/{chunk-3PQNUWJM.js → chunk-EQV2PPN2.js} +2 -4
  45. package/dist/chunk-EQV2PPN2.js.map +1 -0
  46. package/dist/chunk-FUVNHPNL.cjs +4 -0
  47. package/dist/chunk-FUVNHPNL.cjs.map +1 -0
  48. package/dist/{chunk-F6EJEELE.cjs → chunk-HJQ7ANDX.cjs} +6 -6
  49. package/dist/{chunk-F6EJEELE.cjs.map → chunk-HJQ7ANDX.cjs.map} +1 -1
  50. package/dist/{chunk-2GHLV754.cjs → chunk-HV5ND4KF.cjs} +4 -4
  51. package/dist/{chunk-2GHLV754.cjs.map → chunk-HV5ND4KF.cjs.map} +1 -1
  52. package/dist/{chunk-HQPFM22N.cjs → chunk-IB27A3HF.cjs} +16 -16
  53. package/dist/{chunk-HQPFM22N.cjs.map → chunk-IB27A3HF.cjs.map} +1 -1
  54. package/dist/{chunk-BCWRUNMS.cjs → chunk-K3UPABLX.cjs} +38 -38
  55. package/dist/{chunk-BCWRUNMS.cjs.map → chunk-K3UPABLX.cjs.map} +1 -1
  56. package/dist/{chunk-XG3SFWOH.js → chunk-KK5LUATU.js} +3 -3
  57. package/dist/{chunk-XG3SFWOH.js.map → chunk-KK5LUATU.js.map} +1 -1
  58. package/dist/{chunk-VWO3JJXC.js → chunk-LYRPXSHB.js} +4 -4
  59. package/dist/{chunk-VWO3JJXC.js.map → chunk-LYRPXSHB.js.map} +1 -1
  60. package/dist/{chunk-IAXAPVOP.js → chunk-M24QFL6S.js} +4 -4
  61. package/dist/{chunk-IAXAPVOP.js.map → chunk-M24QFL6S.js.map} +1 -1
  62. package/dist/{chunk-5HCVPQTD.js → chunk-M4AX46DS.js} +3 -3
  63. package/dist/{chunk-5HCVPQTD.js.map → chunk-M4AX46DS.js.map} +1 -1
  64. package/dist/{chunk-3WFH6YRI.js → chunk-M635OK6I.js} +4 -4
  65. package/dist/{chunk-3WFH6YRI.js.map → chunk-M635OK6I.js.map} +1 -1
  66. package/dist/{chunk-UTEH2LCJ.cjs → chunk-NLBX7Q47.cjs} +19 -19
  67. package/dist/{chunk-UTEH2LCJ.cjs.map → chunk-NLBX7Q47.cjs.map} +1 -1
  68. package/dist/{chunk-2DGWSOVQ.js → chunk-NMSLDMQ6.js} +3 -3
  69. package/dist/{chunk-2DGWSOVQ.js.map → chunk-NMSLDMQ6.js.map} +1 -1
  70. package/dist/{chunk-PJ6HF3KW.js → chunk-NVMKTP4N.js} +3 -3
  71. package/dist/{chunk-PJ6HF3KW.js.map → chunk-NVMKTP4N.js.map} +1 -1
  72. package/dist/{chunk-4BEHJSL6.js → chunk-QFKTSGBI.js} +3 -3
  73. package/dist/{chunk-4BEHJSL6.js.map → chunk-QFKTSGBI.js.map} +1 -1
  74. package/dist/{chunk-LZBVDMVQ.cjs → chunk-QMDJVXFQ.cjs} +19 -19
  75. package/dist/{chunk-LZBVDMVQ.cjs.map → chunk-QMDJVXFQ.cjs.map} +1 -1
  76. package/dist/{chunk-TIBULEK6.cjs → chunk-SZD4WTRW.cjs} +717 -275
  77. package/dist/chunk-SZD4WTRW.cjs.map +1 -0
  78. package/dist/{chunk-OBIF7QD5.js → chunk-T2CUZA2P.js} +3 -3
  79. package/dist/{chunk-OBIF7QD5.js.map → chunk-T2CUZA2P.js.map} +1 -1
  80. package/dist/{chunk-WHFNGECY.js → chunk-T3JFFQH2.js} +3 -2
  81. package/dist/chunk-T3JFFQH2.js.map +1 -0
  82. package/dist/{chunk-BUY5X7DT.js → chunk-TJHEGJNW.js} +4 -4
  83. package/dist/{chunk-BUY5X7DT.js.map → chunk-TJHEGJNW.js.map} +1 -1
  84. package/dist/{chunk-KTCBGNCZ.cjs → chunk-UU5L5GDY.cjs} +2 -4
  85. package/dist/chunk-UU5L5GDY.cjs.map +1 -0
  86. package/dist/{chunk-S7UXT3V4.cjs → chunk-WM4VQWOZ.cjs} +3 -2
  87. package/dist/chunk-WM4VQWOZ.cjs.map +1 -0
  88. package/dist/{chunk-RNIY63FP.cjs → chunk-WMGV4CS3.cjs} +59 -59
  89. package/dist/{chunk-RNIY63FP.cjs.map → chunk-WMGV4CS3.cjs.map} +1 -1
  90. package/dist/{chunk-5M6ZTQJN.js → chunk-X6PLOE2T.js} +717 -275
  91. package/dist/chunk-X6PLOE2T.js.map +1 -0
  92. package/dist/error/index.cjs +5 -5
  93. package/dist/error/index.d.ts +2 -1
  94. package/dist/error/index.d.ts.map +1 -1
  95. package/dist/error/index.js +1 -1
  96. package/dist/eval/index.cjs +3 -3
  97. package/dist/eval/index.js +1 -1
  98. package/dist/index.cjs +66 -66
  99. package/dist/index.js +15 -15
  100. package/dist/llm/index.cjs +5 -5
  101. package/dist/llm/index.d.ts +1 -0
  102. package/dist/llm/index.d.ts.map +1 -1
  103. package/dist/llm/index.js +1 -1
  104. package/dist/llm/model/gateway-resolver.d.ts +9 -0
  105. package/dist/llm/model/gateway-resolver.d.ts.map +1 -0
  106. package/dist/llm/model/gateways/base.d.ts +5 -4
  107. package/dist/llm/model/gateways/base.d.ts.map +1 -1
  108. package/dist/llm/model/gateways/index.d.ts +1 -0
  109. package/dist/llm/model/gateways/index.d.ts.map +1 -1
  110. package/dist/llm/model/gateways/models-dev.d.ts +3 -2
  111. package/dist/llm/model/gateways/models-dev.d.ts.map +1 -1
  112. package/dist/llm/model/gateways/netlify.d.ts +15 -0
  113. package/dist/llm/model/gateways/netlify.d.ts.map +1 -0
  114. package/dist/llm/model/openai-compatible.d.ts +8 -3
  115. package/dist/llm/model/openai-compatible.d.ts.map +1 -1
  116. package/dist/llm/model/provider-registry.generated.d.ts +8 -370
  117. package/dist/llm/model/provider-registry.generated.d.ts.map +1 -1
  118. package/dist/loop/index.cjs +2 -2
  119. package/dist/loop/index.js +1 -1
  120. package/dist/mastra/index.cjs +2 -2
  121. package/dist/mastra/index.js +1 -1
  122. package/dist/memory/index.cjs +4 -4
  123. package/dist/memory/index.js +1 -1
  124. package/dist/network/vNext/index.cjs +29 -29
  125. package/dist/network/vNext/index.js +2 -2
  126. package/dist/processors/index.cjs +10 -10
  127. package/dist/processors/index.js +1 -1
  128. package/dist/relevance/index.cjs +4 -4
  129. package/dist/relevance/index.js +1 -1
  130. package/dist/scores/index.cjs +9 -9
  131. package/dist/scores/index.js +2 -2
  132. package/dist/scores/scoreTraces/index.cjs +13 -13
  133. package/dist/scores/scoreTraces/index.js +4 -4
  134. package/dist/server/index.cjs +7 -7
  135. package/dist/server/index.js +2 -2
  136. package/dist/storage/index.cjs +25 -25
  137. package/dist/storage/index.js +4 -4
  138. package/dist/stream/index.cjs +4 -4
  139. package/dist/stream/index.js +1 -1
  140. package/dist/telemetry/index.cjs +7 -7
  141. package/dist/telemetry/index.js +1 -1
  142. package/dist/test-utils/llm-mock.cjs +2 -2
  143. package/dist/test-utils/llm-mock.js +1 -1
  144. package/dist/tts/index.cjs +2 -2
  145. package/dist/tts/index.js +1 -1
  146. package/dist/utils.cjs +17 -17
  147. package/dist/utils.js +1 -1
  148. package/dist/vector/index.cjs +4 -4
  149. package/dist/vector/index.js +1 -1
  150. package/dist/voice/index.cjs +4 -4
  151. package/dist/voice/index.js +1 -1
  152. package/dist/workflows/evented/index.cjs +10 -10
  153. package/dist/workflows/evented/index.js +1 -1
  154. package/dist/workflows/index.cjs +12 -12
  155. package/dist/workflows/index.js +1 -1
  156. package/dist/workflows/legacy/index.cjs +22 -22
  157. package/dist/workflows/legacy/index.js +1 -1
  158. package/package.json +1 -1
  159. package/dist/chunk-3PQNUWJM.js.map +0 -1
  160. package/dist/chunk-5M6ZTQJN.js.map +0 -1
  161. package/dist/chunk-KTCBGNCZ.cjs.map +0 -1
  162. package/dist/chunk-S7UXT3V4.cjs.map +0 -1
  163. package/dist/chunk-TIBULEK6.cjs.map +0 -1
  164. package/dist/chunk-WHFNGECY.js.map +0 -1
@@ -1,3 +1,6 @@
1
+ import { InMemoryServerCache } from './chunk-EQV2PPN2.js';
2
+ import { MastraError } from './chunk-T3JFFQH2.js';
3
+
1
4
  // src/llm/model/provider-registry.generated.ts
2
5
  var PROVIDER_REGISTRY = {
3
6
  "moonshotai-cn": {
@@ -6,7 +9,8 @@ var PROVIDER_REGISTRY = {
6
9
  apiKeyHeader: "Authorization",
7
10
  name: "Moonshot AI (China)",
8
11
  models: ["kimi-k2-0711-preview", "kimi-k2-0905-preview", "kimi-k2-turbo-preview"],
9
- docUrl: "https://platform.moonshot.cn/docs/api/chat"
12
+ docUrl: "https://platform.moonshot.cn/docs/api/chat",
13
+ gateway: "models.dev"
10
14
  },
11
15
  lucidquery: {
12
16
  url: "https://lucidquery.com/api/v1/chat/completions",
@@ -14,7 +18,8 @@ var PROVIDER_REGISTRY = {
14
18
  apiKeyHeader: "Authorization",
15
19
  name: "LucidQuery AI",
16
20
  models: ["lucidnova-rf1-100b", "lucidquery-nexus-coder"],
17
- docUrl: "https://lucidquery.com/api/docs"
21
+ docUrl: "https://lucidquery.com/api/docs",
22
+ gateway: "models.dev"
18
23
  },
19
24
  moonshotai: {
20
25
  url: "https://api.moonshot.ai/v1/chat/completions",
@@ -22,7 +27,8 @@ var PROVIDER_REGISTRY = {
22
27
  apiKeyHeader: "Authorization",
23
28
  name: "Moonshot AI",
24
29
  models: ["kimi-k2-0711-preview", "kimi-k2-0905-preview", "kimi-k2-turbo-preview"],
25
- docUrl: "https://platform.moonshot.ai/docs/api/chat"
30
+ docUrl: "https://platform.moonshot.ai/docs/api/chat",
31
+ gateway: "models.dev"
26
32
  },
27
33
  "zai-coding-plan": {
28
34
  url: "https://api.z.ai/api/coding/paas/v4/chat/completions",
@@ -30,7 +36,8 @@ var PROVIDER_REGISTRY = {
30
36
  apiKeyHeader: "Authorization",
31
37
  name: "Z.AI Coding Plan",
32
38
  models: ["glm-4.5", "glm-4.5-air", "glm-4.5-flash", "glm-4.5v", "glm-4.6"],
33
- docUrl: "https://docs.z.ai/devpack/overview"
39
+ docUrl: "https://docs.z.ai/devpack/overview",
40
+ gateway: "models.dev"
34
41
  },
35
42
  alibaba: {
36
43
  url: "https://dashscope-intl.aliyuncs.com/compatible-mode/v1/chat/completions",
@@ -38,7 +45,8 @@ var PROVIDER_REGISTRY = {
38
45
  apiKeyHeader: "Authorization",
39
46
  name: "Alibaba",
40
47
  models: ["qwen3-coder-plus"],
41
- docUrl: "https://www.alibabacloud.com/help/en/model-studio/models"
48
+ docUrl: "https://www.alibabacloud.com/help/en/model-studio/models",
49
+ gateway: "models.dev"
42
50
  },
43
51
  xai: {
44
52
  url: "https://api.x.ai/v1/chat/completions",
@@ -67,7 +75,8 @@ var PROVIDER_REGISTRY = {
67
75
  "grok-code-fast-1",
68
76
  "grok-vision-beta"
69
77
  ],
70
- docUrl: "https://docs.x.ai/docs/models"
78
+ docUrl: "https://docs.x.ai/docs/models",
79
+ gateway: "models.dev"
71
80
  },
72
81
  nvidia: {
73
82
  url: "https://integrate.api.nvidia.com/v1/chat/completions",
@@ -89,7 +98,8 @@ var PROVIDER_REGISTRY = {
89
98
  "qwen/qwen3-235b-a22b",
90
99
  "qwen/qwen3-coder-480b-a35b-instruct"
91
100
  ],
92
- docUrl: "https://docs.api.nvidia.com/nim/"
101
+ docUrl: "https://docs.api.nvidia.com/nim/",
102
+ gateway: "models.dev"
93
103
  },
94
104
  upstage: {
95
105
  url: "https://api.upstage.ai/chat/completions",
@@ -97,7 +107,8 @@ var PROVIDER_REGISTRY = {
97
107
  apiKeyHeader: "Authorization",
98
108
  name: "Upstage",
99
109
  models: ["solar-mini", "solar-pro2"],
100
- docUrl: "https://developers.upstage.ai/docs/apis/chat"
110
+ docUrl: "https://developers.upstage.ai/docs/apis/chat",
111
+ gateway: "models.dev"
101
112
  },
102
113
  groq: {
103
114
  url: "https://api.groq.com/openai/v1/chat/completions",
@@ -123,7 +134,8 @@ var PROVIDER_REGISTRY = {
123
134
  "qwen-qwq-32b",
124
135
  "qwen/qwen3-32b"
125
136
  ],
126
- docUrl: "https://console.groq.com/docs/models"
137
+ docUrl: "https://console.groq.com/docs/models",
138
+ gateway: "models.dev"
127
139
  },
128
140
  "github-copilot": {
129
141
  url: "https://api.githubcopilot.com/chat/completions",
@@ -143,14 +155,14 @@ var PROVIDER_REGISTRY = {
143
155
  "gpt-4.1",
144
156
  "gpt-4o",
145
157
  "gpt-5",
146
- "gpt-5-codex",
147
158
  "gpt-5-mini",
148
159
  "grok-code-fast-1",
149
160
  "o3",
150
161
  "o3-mini",
151
162
  "o4-mini"
152
163
  ],
153
- docUrl: "https://docs.github.com/en/copilot"
164
+ docUrl: "https://docs.github.com/en/copilot",
165
+ gateway: "models.dev"
154
166
  },
155
167
  mistral: {
156
168
  url: "https://api.mistral.ai/v1/chat/completions",
@@ -178,7 +190,8 @@ var PROVIDER_REGISTRY = {
178
190
  "pixtral-12b",
179
191
  "pixtral-large-latest"
180
192
  ],
181
- docUrl: "https://docs.mistral.ai/getting-started/models/"
193
+ docUrl: "https://docs.mistral.ai/getting-started/models/",
194
+ gateway: "models.dev"
182
195
  },
183
196
  vercel: {
184
197
  url: "https://ai-gateway.vercel.sh/v1/chat/completions",
@@ -228,7 +241,6 @@ var PROVIDER_REGISTRY = {
228
241
  "openai/gpt-4o",
229
242
  "openai/gpt-4o-mini",
230
243
  "openai/gpt-5",
231
- "openai/gpt-5-codex",
232
244
  "openai/gpt-5-mini",
233
245
  "openai/gpt-5-nano",
234
246
  "openai/gpt-oss-120b",
@@ -250,7 +262,8 @@ var PROVIDER_REGISTRY = {
250
262
  "xai/grok-4-fast-non-reasoning",
251
263
  "xai/grok-code-fast-1"
252
264
  ],
253
- docUrl: "https://github.com/vercel/ai/tree/5eb85cc45a259553501f535b8ac79a77d0e79223/packages/gateway"
265
+ docUrl: "https://github.com/vercel/ai/tree/5eb85cc45a259553501f535b8ac79a77d0e79223/packages/gateway",
266
+ gateway: "models.dev"
254
267
  },
255
268
  deepseek: {
256
269
  url: "https://api.deepseek.com/chat/completions",
@@ -258,7 +271,8 @@ var PROVIDER_REGISTRY = {
258
271
  apiKeyHeader: "Authorization",
259
272
  name: "DeepSeek",
260
273
  models: ["deepseek-chat", "deepseek-reasoner"],
261
- docUrl: "https://platform.deepseek.com/api-docs/pricing"
274
+ docUrl: "https://platform.deepseek.com/api-docs/pricing",
275
+ gateway: "models.dev"
262
276
  },
263
277
  "alibaba-cn": {
264
278
  url: "https://dashscope.aliyuncs.com/compatible-mode/v1/chat/completions",
@@ -266,7 +280,8 @@ var PROVIDER_REGISTRY = {
266
280
  apiKeyHeader: "Authorization",
267
281
  name: "Alibaba (China)",
268
282
  models: ["qwen3-coder-plus"],
269
- docUrl: "https://www.alibabacloud.com/help/en/model-studio/models"
283
+ docUrl: "https://www.alibabacloud.com/help/en/model-studio/models",
284
+ gateway: "models.dev"
270
285
  },
271
286
  venice: {
272
287
  url: "https://api.venice.ai/api/v1/chat/completions",
@@ -288,7 +303,8 @@ var PROVIDER_REGISTRY = {
288
303
  "qwen3-4b",
289
304
  "venice-uncensored"
290
305
  ],
291
- docUrl: "https://docs.venice.ai"
306
+ docUrl: "https://docs.venice.ai",
307
+ gateway: "models.dev"
292
308
  },
293
309
  chutes: {
294
310
  url: "https://llm.chutes.ai/v1/chat/completions",
@@ -327,7 +343,8 @@ var PROVIDER_REGISTRY = {
327
343
  "zai-org/GLM-4.5-FP8",
328
344
  "zai-org/GLM-4.5-turbo"
329
345
  ],
330
- docUrl: "https://llm.chutes.ai/v1/models"
346
+ docUrl: "https://llm.chutes.ai/v1/models",
347
+ gateway: "models.dev"
331
348
  },
332
349
  cortecs: {
333
350
  url: "https://api.cortecs.ai/v1/chat/completions",
@@ -346,7 +363,8 @@ var PROVIDER_REGISTRY = {
346
363
  "qwen3-32b",
347
364
  "qwen3-coder-480b-a35b-instruct"
348
365
  ],
349
- docUrl: "https://api.cortecs.ai/v1/models"
366
+ docUrl: "https://api.cortecs.ai/v1/models",
367
+ gateway: "models.dev"
350
368
  },
351
369
  "github-models": {
352
370
  url: "https://models.github.ai/inference/chat/completions",
@@ -410,7 +428,8 @@ var PROVIDER_REGISTRY = {
410
428
  "xai/grok-3",
411
429
  "xai/grok-3-mini"
412
430
  ],
413
- docUrl: "https://docs.github.com/en/github-models"
431
+ docUrl: "https://docs.github.com/en/github-models",
432
+ gateway: "models.dev"
414
433
  },
415
434
  togetherai: {
416
435
  url: "https://api.together.xyz/v1/chat/completions",
@@ -425,7 +444,8 @@ var PROVIDER_REGISTRY = {
425
444
  "moonshotai/Kimi-K2-Instruct",
426
445
  "openai/gpt-oss-120b"
427
446
  ],
428
- docUrl: "https://docs.together.ai/docs/serverless-models"
447
+ docUrl: "https://docs.together.ai/docs/serverless-models",
448
+ gateway: "models.dev"
429
449
  },
430
450
  baseten: {
431
451
  url: "https://inference.baseten.co/v1/chat/completions",
@@ -433,7 +453,8 @@ var PROVIDER_REGISTRY = {
433
453
  apiKeyHeader: "Authorization",
434
454
  name: "Baseten",
435
455
  models: ["Qwen3/Qwen3-Coder-480B-A35B-Instruct", "moonshotai/Kimi-K2-Instruct-0905"],
436
- docUrl: "https://docs.baseten.co/development/model-apis/overview"
456
+ docUrl: "https://docs.baseten.co/development/model-apis/overview",
457
+ gateway: "models.dev"
437
458
  },
438
459
  huggingface: {
439
460
  url: "https://router.huggingface.co/v1/chat/completions",
@@ -452,7 +473,8 @@ var PROVIDER_REGISTRY = {
452
473
  "zai-org/GLM-4.5",
453
474
  "zai-org/GLM-4.5-Air"
454
475
  ],
455
- docUrl: "https://huggingface.co/docs/inference-providers"
476
+ docUrl: "https://huggingface.co/docs/inference-providers",
477
+ gateway: "models.dev"
456
478
  },
457
479
  opencode: {
458
480
  url: "https://opencode.ai/zen/v1/chat/completions",
@@ -466,13 +488,13 @@ var PROVIDER_REGISTRY = {
466
488
  "claude-sonnet-4-5",
467
489
  "code-supernova",
468
490
  "gpt-5",
469
- "gpt-5-codex",
470
491
  "grok-code",
471
492
  "kimi-k2",
472
493
  "qwen3-coder",
473
494
  "qwen3-max"
474
495
  ],
475
- docUrl: "https://opencode.ai/docs"
496
+ docUrl: "https://opencode.ai/docs",
497
+ gateway: "models.dev"
476
498
  },
477
499
  fastrouter: {
478
500
  url: "https://go.fastrouter.ai/api/v1/chat/completions",
@@ -495,7 +517,8 @@ var PROVIDER_REGISTRY = {
495
517
  "qwen/qwen3-coder",
496
518
  "x-ai/grok-4"
497
519
  ],
498
- docUrl: "https://fastrouter.ai/models"
520
+ docUrl: "https://fastrouter.ai/models",
521
+ gateway: "models.dev"
499
522
  },
500
523
  google: {
501
524
  url: "https://generativelanguage.googleapis.com/v1beta/chat/completions",
@@ -522,7 +545,8 @@ var PROVIDER_REGISTRY = {
522
545
  "gemini-flash-lite-latest",
523
546
  "gemini-live-2.5-flash-preview-native-audio"
524
547
  ],
525
- docUrl: "https://ai.google.dev/gemini-api/docs/pricing"
548
+ docUrl: "https://ai.google.dev/gemini-api/docs/pricing",
549
+ gateway: "models.dev"
526
550
  },
527
551
  inception: {
528
552
  url: "https://api.inceptionlabs.ai/v1/chat/completions",
@@ -530,7 +554,8 @@ var PROVIDER_REGISTRY = {
530
554
  apiKeyHeader: "Authorization",
531
555
  name: "Inception",
532
556
  models: ["mercury", "mercury-coder"],
533
- docUrl: "https://platform.inceptionlabs.ai/docs"
557
+ docUrl: "https://platform.inceptionlabs.ai/docs",
558
+ gateway: "models.dev"
534
559
  },
535
560
  wandb: {
536
561
  url: "https://api.inference.wandb.ai/v1/chat/completions",
@@ -549,7 +574,8 @@ var PROVIDER_REGISTRY = {
549
574
  "microsoft/Phi-4-mini-instruct",
550
575
  "moonshotai/Kimi-K2-Instruct"
551
576
  ],
552
- docUrl: "https://weave-docs.wandb.ai/guides/integrations/inference/"
577
+ docUrl: "https://weave-docs.wandb.ai/guides/integrations/inference/",
578
+ gateway: "models.dev"
553
579
  },
554
580
  openai: {
555
581
  url: "https://api.openai.com/v1/chat/completions",
@@ -557,7 +583,6 @@ var PROVIDER_REGISTRY = {
557
583
  apiKeyHeader: "Authorization",
558
584
  name: "OpenAI",
559
585
  models: [
560
- "codex-mini-latest",
561
586
  "gpt-3.5-turbo",
562
587
  "gpt-4",
563
588
  "gpt-4-turbo",
@@ -571,7 +596,6 @@ var PROVIDER_REGISTRY = {
571
596
  "gpt-4o-mini",
572
597
  "gpt-5",
573
598
  "gpt-5-chat-latest",
574
- "gpt-5-codex",
575
599
  "gpt-5-mini",
576
600
  "gpt-5-nano",
577
601
  "o1",
@@ -585,7 +609,8 @@ var PROVIDER_REGISTRY = {
585
609
  "o4-mini",
586
610
  "o4-mini-deep-research"
587
611
  ],
588
- docUrl: "https://platform.openai.com/docs/models"
612
+ docUrl: "https://platform.openai.com/docs/models",
613
+ gateway: "models.dev"
589
614
  },
590
615
  "zhipuai-coding-plan": {
591
616
  url: "https://open.bigmodel.cn/api/coding/paas/v4/chat/completions",
@@ -593,7 +618,8 @@ var PROVIDER_REGISTRY = {
593
618
  apiKeyHeader: "Authorization",
594
619
  name: "Zhipu AI Coding Plan",
595
620
  models: ["glm-4.5", "glm-4.5-air", "glm-4.5-flash", "glm-4.5v", "glm-4.6"],
596
- docUrl: "https://docs.bigmodel.cn/cn/coding-plan/overview"
621
+ docUrl: "https://docs.bigmodel.cn/cn/coding-plan/overview",
622
+ gateway: "models.dev"
597
623
  },
598
624
  perplexity: {
599
625
  url: "https://api.perplexity.ai/chat/completions",
@@ -601,7 +627,8 @@ var PROVIDER_REGISTRY = {
601
627
  apiKeyHeader: "Authorization",
602
628
  name: "Perplexity",
603
629
  models: ["sonar", "sonar-pro", "sonar-reasoning", "sonar-reasoning-pro"],
604
- docUrl: "https://docs.perplexity.ai"
630
+ docUrl: "https://docs.perplexity.ai",
631
+ gateway: "models.dev"
605
632
  },
606
633
  openrouter: {
607
634
  url: "https://openrouter.ai/api/v1/chat/completions",
@@ -666,7 +693,6 @@ var PROVIDER_REGISTRY = {
666
693
  "openai/gpt-4o-mini",
667
694
  "openai/gpt-5",
668
695
  "openai/gpt-5-chat",
669
- "openai/gpt-5-codex",
670
696
  "openai/gpt-5-mini",
671
697
  "openai/gpt-5-nano",
672
698
  "openai/gpt-oss-120b",
@@ -712,7 +738,8 @@ var PROVIDER_REGISTRY = {
712
738
  "z-ai/glm-4.5-air:free",
713
739
  "z-ai/glm-4.5v"
714
740
  ],
715
- docUrl: "https://openrouter.ai/models"
741
+ docUrl: "https://openrouter.ai/models",
742
+ gateway: "models.dev"
716
743
  },
717
744
  synthetic: {
718
745
  url: "https://api.synthetic.new/v1/chat/completions",
@@ -741,7 +768,8 @@ var PROVIDER_REGISTRY = {
741
768
  "hf:openai/gpt-oss-120b",
742
769
  "hf:zai-org/GLM-4.5"
743
770
  ],
744
- docUrl: "https://synthetic.new/pricing"
771
+ docUrl: "https://synthetic.new/pricing",
772
+ gateway: "models.dev"
745
773
  },
746
774
  deepinfra: {
747
775
  url: "https://api.deepinfra.com/v1/openai/chat/completions",
@@ -754,7 +782,8 @@ var PROVIDER_REGISTRY = {
754
782
  "moonshotai/Kimi-K2-Instruct",
755
783
  "zai-org/GLM-4.5"
756
784
  ],
757
- docUrl: "https://deepinfra.com/models"
785
+ docUrl: "https://deepinfra.com/models",
786
+ gateway: "models.dev"
758
787
  },
759
788
  zhipuai: {
760
789
  url: "https://open.bigmodel.cn/api/paas/v4/chat/completions",
@@ -762,7 +791,8 @@ var PROVIDER_REGISTRY = {
762
791
  apiKeyHeader: "Authorization",
763
792
  name: "Zhipu AI",
764
793
  models: ["glm-4.5", "glm-4.5-air", "glm-4.5-flash", "glm-4.5v", "glm-4.6"],
765
- docUrl: "https://docs.z.ai/guides/overview/pricing"
794
+ docUrl: "https://docs.z.ai/guides/overview/pricing",
795
+ gateway: "models.dev"
766
796
  },
767
797
  submodel: {
768
798
  url: "https://llm.submodel.ai/v1/chat/completions",
@@ -780,7 +810,8 @@ var PROVIDER_REGISTRY = {
780
810
  "zai-org/GLM-4.5-Air",
781
811
  "zai-org/GLM-4.5-FP8"
782
812
  ],
783
- docUrl: "https://submodel.gitbook.io"
813
+ docUrl: "https://submodel.gitbook.io",
814
+ gateway: "models.dev"
784
815
  },
785
816
  zai: {
786
817
  url: "https://api.z.ai/api/paas/v4/chat/completions",
@@ -788,7 +819,8 @@ var PROVIDER_REGISTRY = {
788
819
  apiKeyHeader: "Authorization",
789
820
  name: "Z.AI",
790
821
  models: ["glm-4.5", "glm-4.5-air", "glm-4.5-flash", "glm-4.5v", "glm-4.6"],
791
- docUrl: "https://docs.z.ai/guides/overview/pricing"
822
+ docUrl: "https://docs.z.ai/guides/overview/pricing",
823
+ gateway: "models.dev"
792
824
  },
793
825
  inference: {
794
826
  url: "https://inference.net/v1/chat/completions",
@@ -806,7 +838,8 @@ var PROVIDER_REGISTRY = {
806
838
  "qwen/qwen-2.5-7b-vision-instruct",
807
839
  "qwen/qwen3-embedding-4b"
808
840
  ],
809
- docUrl: "https://inference.net/models"
841
+ docUrl: "https://inference.net/models",
842
+ gateway: "models.dev"
810
843
  },
811
844
  requesty: {
812
845
  url: "https://router.requesty.ai/v1/chat/completions",
@@ -828,7 +861,8 @@ var PROVIDER_REGISTRY = {
828
861
  "openai/gpt-5-nano",
829
862
  "openai/o4-mini"
830
863
  ],
831
- docUrl: "https://requesty.ai/solution/llm-routing/models"
864
+ docUrl: "https://requesty.ai/solution/llm-routing/models",
865
+ gateway: "models.dev"
832
866
  },
833
867
  morph: {
834
868
  url: "https://api.morphllm.com/v1/chat/completions",
@@ -836,7 +870,8 @@ var PROVIDER_REGISTRY = {
836
870
  apiKeyHeader: "Authorization",
837
871
  name: "Morph",
838
872
  models: ["auto", "morph-v3-fast", "morph-v3-large"],
839
- docUrl: "https://docs.morphllm.com/api-reference/introduction"
873
+ docUrl: "https://docs.morphllm.com/api-reference/introduction",
874
+ gateway: "models.dev"
840
875
  },
841
876
  lmstudio: {
842
877
  url: "http://127.0.0.1:1234/v1/chat/completions",
@@ -844,7 +879,8 @@ var PROVIDER_REGISTRY = {
844
879
  apiKeyHeader: "Authorization",
845
880
  name: "LMStudio",
846
881
  models: ["openai/gpt-oss-20b", "qwen/qwen3-30b-a3b-2507", "qwen/qwen3-coder-30b"],
847
- docUrl: "https://lmstudio.ai/models"
882
+ docUrl: "https://lmstudio.ai/models",
883
+ gateway: "models.dev"
848
884
  },
849
885
  anthropic: {
850
886
  url: "https://api.anthropic.com/v1/chat/completions",
@@ -864,7 +900,8 @@ var PROVIDER_REGISTRY = {
864
900
  "claude-sonnet-4-20250514",
865
901
  "claude-sonnet-4-5-20250929"
866
902
  ],
867
- docUrl: "https://docs.anthropic.com/en/docs/about-claude/models"
903
+ docUrl: "https://docs.anthropic.com/en/docs/about-claude/models",
904
+ gateway: "models.dev"
868
905
  },
869
906
  "fireworks-ai": {
870
907
  url: "https://api.fireworks.ai/inference/v1/chat/completions",
@@ -883,7 +920,8 @@ var PROVIDER_REGISTRY = {
883
920
  "accounts/fireworks/models/qwen3-235b-a22b",
884
921
  "accounts/fireworks/models/qwen3-coder-480b-a35b-instruct"
885
922
  ],
886
- docUrl: "https://fireworks.ai/docs/"
923
+ docUrl: "https://fireworks.ai/docs/",
924
+ gateway: "models.dev"
887
925
  },
888
926
  modelscope: {
889
927
  url: "https://api-inference.modelscope.cn/v1/chat/completions",
@@ -899,7 +937,8 @@ var PROVIDER_REGISTRY = {
899
937
  "Qwen/Qwen3-Coder-480B-A35B-Instruct",
900
938
  "ZhipuAI/GLM-4.5"
901
939
  ],
902
- docUrl: "https://modelscope.cn/docs/model-service/API-Inference/intro"
940
+ docUrl: "https://modelscope.cn/docs/model-service/API-Inference/intro",
941
+ gateway: "models.dev"
903
942
  },
904
943
  llama: {
905
944
  url: "https://api.llama.com/compat/v1/chat/completions",
@@ -915,7 +954,8 @@ var PROVIDER_REGISTRY = {
915
954
  "llama-4-maverick-17b-128e-instruct-fp8",
916
955
  "llama-4-scout-17b-16e-instruct-fp8"
917
956
  ],
918
- docUrl: "https://llama.developer.meta.com/docs/models"
957
+ docUrl: "https://llama.developer.meta.com/docs/models",
958
+ gateway: "models.dev"
919
959
  },
920
960
  cerebras: {
921
961
  url: "https://api.cerebras.ai/v1/chat/completions",
@@ -923,7 +963,48 @@ var PROVIDER_REGISTRY = {
923
963
  apiKeyHeader: "Authorization",
924
964
  name: "Cerebras",
925
965
  models: ["gpt-oss-120b", "qwen-3-235b-a22b-instruct-2507", "qwen-3-coder-480b"],
926
- docUrl: "https://inference-docs.cerebras.ai/models/overview"
966
+ docUrl: "https://inference-docs.cerebras.ai/models/overview",
967
+ gateway: "models.dev"
968
+ },
969
+ netlify: {
970
+ apiKeyEnvVar: ["NETLIFY_TOKEN", "NETLIFY_SITE_ID"],
971
+ apiKeyHeader: "Authorization",
972
+ name: "Netlify",
973
+ gateway: "netlify",
974
+ models: [
975
+ "anthropic/claude-opus-4-1-20250805",
976
+ "anthropic/claude-opus-4-20250514",
977
+ "anthropic/claude-sonnet-4-20250514",
978
+ "anthropic/claude-3-7-sonnet-20250219",
979
+ "anthropic/claude-3-5-haiku-20241022",
980
+ "anthropic/claude-sonnet-4-5-20250929",
981
+ "anthropic/claude-3-7-sonnet-latest",
982
+ "anthropic/claude-3-5-haiku-latest",
983
+ "anthropic/claude-3-haiku-20240307",
984
+ "gemini/gemini-flash-latest",
985
+ "gemini/gemini-2.5-flash",
986
+ "gemini/gemini-2.5-flash-lite-preview-09-2025",
987
+ "gemini/gemini-2.5-flash-lite",
988
+ "gemini/gemini-2.0-flash",
989
+ "gemini/gemini-2.0-flash-lite",
990
+ "gemini/gemini-2.5-pro",
991
+ "gemini/gemini-2.5-flash-preview-09-2025",
992
+ "gemini/gemini-flash-lite-latest",
993
+ "gemini/gemini-2.5-flash-image-preview",
994
+ "openai/o3",
995
+ "openai/gpt-5-mini",
996
+ "openai/gpt-4.1-nano",
997
+ "openai/o4-mini",
998
+ "openai/o3-mini",
999
+ "openai/codex-mini-latest",
1000
+ "openai/gpt-5",
1001
+ "openai/gpt-5-codex",
1002
+ "openai/gpt-5-nano",
1003
+ "openai/gpt-4.1",
1004
+ "openai/gpt-4.1-mini",
1005
+ "openai/gpt-4o",
1006
+ "openai/gpt-4o-mini"
1007
+ ]
927
1008
  }
928
1009
  };
929
1010
  function getProviderConfig(providerId) {
@@ -947,33 +1028,328 @@ function parseModelString(modelString) {
947
1028
  };
948
1029
  }
949
1030
 
1031
+ // src/llm/model/gateways/base.ts
1032
+ var MastraModelGateway = class {
1033
+ };
1034
+
1035
+ // src/llm/model/gateways/models-dev.ts
1036
+ var OPENAI_COMPATIBLE_OVERRIDES = {
1037
+ openai: {
1038
+ url: "https://api.openai.com/v1/chat/completions"
1039
+ },
1040
+ anthropic: {
1041
+ url: "https://api.anthropic.com/v1/chat/completions",
1042
+ apiKeyHeader: "x-api-key"
1043
+ },
1044
+ cerebras: {
1045
+ url: "https://api.cerebras.ai/v1/chat/completions"
1046
+ },
1047
+ xai: {
1048
+ url: "https://api.x.ai/v1/chat/completions"
1049
+ },
1050
+ mistral: {
1051
+ url: "https://api.mistral.ai/v1/chat/completions"
1052
+ },
1053
+ google: {
1054
+ url: "https://generativelanguage.googleapis.com/v1beta/chat/completions"
1055
+ },
1056
+ groq: {
1057
+ url: "https://api.groq.com/openai/v1/chat/completions"
1058
+ },
1059
+ togetherai: {
1060
+ url: "https://api.together.xyz/v1/chat/completions"
1061
+ },
1062
+ deepinfra: {
1063
+ url: "https://api.deepinfra.com/v1/openai/chat/completions"
1064
+ },
1065
+ perplexity: {
1066
+ url: "https://api.perplexity.ai/chat/completions"
1067
+ },
1068
+ vercel: {
1069
+ url: "https://ai-gateway.vercel.sh/v1/chat/completions",
1070
+ apiKeyEnvVar: "AI_GATEWAY_API_KEY"
1071
+ }
1072
+ };
1073
+ var ModelsDevGateway = class extends MastraModelGateway {
1074
+ name = "models.dev";
1075
+ prefix = void 0;
1076
+ // No prefix for registry gateway
1077
+ providerConfigs = {};
1078
+ constructor(providerConfigs) {
1079
+ super();
1080
+ if (providerConfigs) this.providerConfigs = providerConfigs;
1081
+ }
1082
+ async fetchProviders() {
1083
+ console.info("Fetching providers from models.dev API...");
1084
+ const response = await fetch("https://models.dev/api.json");
1085
+ if (!response.ok) {
1086
+ throw new Error(`Failed to fetch from models.dev: ${response.statusText}`);
1087
+ }
1088
+ const data = await response.json();
1089
+ const providerConfigs = {};
1090
+ for (const [providerId, providerInfo] of Object.entries(data)) {
1091
+ if (!providerInfo || typeof providerInfo !== "object" || !providerInfo.models) continue;
1092
+ const normalizedId = providerId;
1093
+ const isOpenAICompatible = providerInfo.npm === "@ai-sdk/openai-compatible" || providerInfo.npm === "@ai-sdk/gateway" || // Vercel AI Gateway is OpenAI-compatible
1094
+ normalizedId in OPENAI_COMPATIBLE_OVERRIDES;
1095
+ const hasApiAndEnv = providerInfo.api && providerInfo.env && providerInfo.env.length > 0;
1096
+ if (isOpenAICompatible || hasApiAndEnv) {
1097
+ const modelIds = Object.keys(providerInfo.models).sort();
1098
+ let url = providerInfo.api || OPENAI_COMPATIBLE_OVERRIDES[normalizedId]?.url;
1099
+ if (url && !url.includes("/chat/completions") && !url.includes("/messages")) {
1100
+ url = url.replace(/\/$/, "") + "/chat/completions";
1101
+ }
1102
+ if (!url) {
1103
+ console.info(`Skipping ${normalizedId}: No API URL available`);
1104
+ continue;
1105
+ }
1106
+ const apiKeyEnvVar = providerInfo.env?.[0] || `${normalizedId.toUpperCase().replace(/-/g, "_")}_API_KEY`;
1107
+ const apiKeyHeader = OPENAI_COMPATIBLE_OVERRIDES[normalizedId]?.apiKeyHeader || "Authorization";
1108
+ providerConfigs[normalizedId] = {
1109
+ url,
1110
+ apiKeyEnvVar,
1111
+ apiKeyHeader,
1112
+ name: providerInfo.name || providerId.charAt(0).toUpperCase() + providerId.slice(1),
1113
+ models: modelIds.filter((id) => !id.includes(`codex`)),
1114
+ // codex requires responses api
1115
+ docUrl: providerInfo.doc,
1116
+ // Include documentation URL if available
1117
+ gateway: `models.dev`
1118
+ };
1119
+ } else {
1120
+ console.info(`Skipped provider ${providerInfo.name}`);
1121
+ }
1122
+ }
1123
+ this.providerConfigs = providerConfigs;
1124
+ console.info(`Found ${Object.keys(providerConfigs).length} OpenAI-compatible providers`);
1125
+ console.info("Providers:", Object.keys(providerConfigs).sort());
1126
+ return providerConfigs;
1127
+ }
1128
+ buildUrl(modelId, envVars) {
1129
+ const [provider, ...modelParts] = modelId.split("/");
1130
+ if (!provider || !modelParts.length) {
1131
+ return false;
1132
+ }
1133
+ const config = this.providerConfigs[provider];
1134
+ if (!config?.url) {
1135
+ return false;
1136
+ }
1137
+ const baseUrlEnvVar = `${provider.toUpperCase().replace(/-/g, "_")}_BASE_URL`;
1138
+ const customBaseUrl = envVars[baseUrlEnvVar];
1139
+ return customBaseUrl || config.url;
1140
+ }
1141
+ buildHeaders(modelId, envVars) {
1142
+ const [provider] = modelId.split("/");
1143
+ if (!provider) {
1144
+ return {};
1145
+ }
1146
+ const config = this.providerConfigs[provider];
1147
+ if (!config) {
1148
+ return {};
1149
+ }
1150
+ const apiKey = typeof config.apiKeyEnvVar === `string` ? envVars[config.apiKeyEnvVar] : void 0;
1151
+ if (!apiKey) {
1152
+ return {};
1153
+ }
1154
+ const headers = {};
1155
+ if (config.apiKeyHeader === "Authorization" || !config.apiKeyHeader) {
1156
+ headers["Authorization"] = `Bearer ${apiKey}`;
1157
+ } else {
1158
+ headers[config.apiKeyHeader] = apiKey;
1159
+ }
1160
+ if (provider === "anthropic") {
1161
+ headers["anthropic-version"] = "2023-06-01";
1162
+ }
1163
+ return headers;
1164
+ }
1165
+ };
1166
+
1167
+ // src/llm/model/gateways/netlify.ts
1168
+ var NetlifyGateway = class extends MastraModelGateway {
1169
+ name = "netlify";
1170
+ prefix = "netlify";
1171
+ // All providers will be prefixed with "netlify/"
1172
+ tokenCache = new InMemoryServerCache();
1173
+ async fetchProviders() {
1174
+ console.info("Fetching providers from Netlify AI Gateway...");
1175
+ const response = await fetch("https://api.netlify.com/api/v1/ai-gateway/providers");
1176
+ if (!response.ok) {
1177
+ throw new Error(`Failed to fetch from Netlify: ${response.statusText}`);
1178
+ }
1179
+ const data = await response.json();
1180
+ const netlify = {
1181
+ apiKeyEnvVar: ["NETLIFY_TOKEN", "NETLIFY_SITE_ID"],
1182
+ apiKeyHeader: "Authorization",
1183
+ // Netlify uses standard Bearer auth
1184
+ name: `Netlify`,
1185
+ gateway: `netlify`,
1186
+ models: []
1187
+ };
1188
+ for (const [providerId, provider] of Object.entries(data.providers)) {
1189
+ for (const model of provider.models) {
1190
+ netlify.models.push(`${providerId}/${model}`);
1191
+ }
1192
+ }
1193
+ console.info(`Found ${Object.keys(data.providers).length} models via Netlify Gateway`);
1194
+ return { netlify };
1195
+ }
1196
+ async buildUrl(modelId, envVars) {
1197
+ if (!modelId.startsWith(`${this.prefix}/`)) {
1198
+ return false;
1199
+ }
1200
+ const parts = modelId.split("/");
1201
+ if (parts.length < 3) {
1202
+ return false;
1203
+ }
1204
+ const provider = parts[1];
1205
+ if (!provider) {
1206
+ return false;
1207
+ }
1208
+ const siteId = envVars["NETLIFY_SITE_ID"];
1209
+ const netlifyToken = envVars["NETLIFY_TOKEN"];
1210
+ if (!netlifyToken) {
1211
+ throw new MastraError({
1212
+ id: "NETLIFY_GATEWAY_NO_TOKEN",
1213
+ domain: "LLM",
1214
+ category: "UNKNOWN",
1215
+ text: `Missing NETLIFY_TOKEN environment variable required for model: ${modelId}`
1216
+ });
1217
+ }
1218
+ if (!siteId) {
1219
+ throw new MastraError({
1220
+ id: "NETLIFY_GATEWAY_NO_SITE_ID",
1221
+ domain: "LLM",
1222
+ category: "UNKNOWN",
1223
+ text: `Missing NETLIFY_SITE_ID environment variable required for model: ${modelId}`
1224
+ });
1225
+ }
1226
+ try {
1227
+ const tokenData = await this.getOrFetchToken(siteId, netlifyToken);
1228
+ return `${tokenData.url}chat/completions`;
1229
+ } catch (error) {
1230
+ throw new MastraError({
1231
+ id: "NETLIFY_GATEWAY_TOKEN_ERROR",
1232
+ domain: "LLM",
1233
+ category: "UNKNOWN",
1234
+ text: `Failed to get Netlify AI Gateway token for model ${modelId}: ${error instanceof Error ? error.message : String(error)}`
1235
+ });
1236
+ }
1237
+ }
1238
+ /**
1239
+ * Get cached token or fetch a new site-specific AI Gateway token from Netlify
1240
+ */
1241
+ async getOrFetchToken(siteId, netlifyToken) {
1242
+ const cacheKey = `netlify-token:${siteId}:${netlifyToken}`;
1243
+ const cached = await this.tokenCache.get(cacheKey);
1244
+ if (cached && cached.expiresAt > Date.now() / 1e3 + 60) {
1245
+ return { token: cached.token, url: cached.url };
1246
+ }
1247
+ const response = await fetch(`https://api.netlify.com/api/v1/sites/${siteId}/ai-gateway/token`, {
1248
+ method: "GET",
1249
+ headers: {
1250
+ Authorization: `Bearer ${netlifyToken}`
1251
+ }
1252
+ });
1253
+ if (!response.ok) {
1254
+ const error = await response.text();
1255
+ throw new Error(`Failed to get Netlify AI Gateway token: ${response.status} ${error}`);
1256
+ }
1257
+ const tokenResponse = await response.json();
1258
+ await this.tokenCache.set(cacheKey, {
1259
+ token: tokenResponse.token,
1260
+ url: tokenResponse.url,
1261
+ expiresAt: tokenResponse.expires_at
1262
+ });
1263
+ return { token: tokenResponse.token, url: tokenResponse.url };
1264
+ }
1265
+ async buildHeaders(modelId, envVars) {
1266
+ const siteId = envVars["NETLIFY_SITE_ID"];
1267
+ const netlifyToken = envVars["NETLIFY_TOKEN"];
1268
+ if (!netlifyToken) {
1269
+ throw new MastraError({
1270
+ id: "NETLIFY_GATEWAY_NO_TOKEN",
1271
+ domain: "LLM",
1272
+ category: "UNKNOWN",
1273
+ text: `Missing NETLIFY_TOKEN environment variable required for model: ${modelId}`
1274
+ });
1275
+ }
1276
+ if (!siteId) {
1277
+ throw new MastraError({
1278
+ id: "NETLIFY_GATEWAY_NO_SITE_ID",
1279
+ domain: "LLM",
1280
+ category: "UNKNOWN",
1281
+ text: `Missing NETLIFY_SITE_ID environment variable required for model: ${modelId}`
1282
+ });
1283
+ }
1284
+ try {
1285
+ const tokenData = await this.getOrFetchToken(siteId, netlifyToken);
1286
+ return {
1287
+ Authorization: `Bearer ${tokenData.token}`
1288
+ };
1289
+ } catch (error) {
1290
+ throw new MastraError({
1291
+ id: "NETLIFY_GATEWAY_TOKEN_ERROR",
1292
+ domain: "LLM",
1293
+ category: "UNKNOWN",
1294
+ text: `Failed to get Netlify AI Gateway token for model ${modelId}: ${error instanceof Error ? error.message : String(error)}`
1295
+ });
1296
+ }
1297
+ }
1298
+ };
1299
+
1300
+ // src/llm/model/gateway-resolver.ts
1301
+ function getStaticProvidersByGateway(name) {
1302
+ return Object.fromEntries(Object.entries(PROVIDER_REGISTRY).filter(([_provider, config]) => config.gateway === name));
1303
+ }
1304
+ var gateways = [new NetlifyGateway(), new ModelsDevGateway(getStaticProvidersByGateway(`models.dev`))];
1305
+ function findGatewayForModel(modelId) {
1306
+ const prefixedGateway = gateways.find((g) => g.prefix && modelId.startsWith(`${g.prefix}/`));
1307
+ if (prefixedGateway) {
1308
+ return prefixedGateway;
1309
+ }
1310
+ const unprefixedGateways = gateways.filter((g) => !g.prefix);
1311
+ for (const gateway of unprefixedGateways) {
1312
+ return gateway;
1313
+ }
1314
+ return null;
1315
+ }
1316
+ async function resolveModelConfig(modelId, envVars = process.env) {
1317
+ const gateway = findGatewayForModel(modelId);
1318
+ if (!gateway) {
1319
+ return { url: false, headers: {}, resolvedModelId: modelId };
1320
+ }
1321
+ const url = await gateway.buildUrl(modelId, envVars);
1322
+ if (url === false) {
1323
+ return { url: false, headers: {}, resolvedModelId: modelId };
1324
+ }
1325
+ const headers = gateway.buildHeaders ? await gateway.buildHeaders(modelId, envVars) : {};
1326
+ let resolvedModelId = modelId;
1327
+ const prefix = gateway.prefix ? `${gateway.prefix}/` : null;
1328
+ if (prefix && resolvedModelId.startsWith(prefix)) {
1329
+ resolvedModelId = resolvedModelId.substring(prefix.length);
1330
+ }
1331
+ const firstSlashIndex = resolvedModelId.indexOf("/");
1332
+ if (firstSlashIndex !== -1) {
1333
+ resolvedModelId = resolvedModelId.substring(firstSlashIndex + 1);
1334
+ }
1335
+ return { url, headers, resolvedModelId };
1336
+ }
1337
+
950
1338
  // src/llm/model/openai-compatible.ts
951
1339
  function resolveApiKey({ provider, apiKey }) {
952
1340
  if (apiKey) return apiKey;
953
1341
  if (provider) {
954
1342
  const config = getProviderConfig(provider);
955
- if (config?.apiKeyEnvVar) {
1343
+ if (typeof config?.apiKeyEnvVar === `string`) {
956
1344
  return process.env[config.apiKeyEnvVar];
957
1345
  }
958
- }
959
- return void 0;
960
- }
961
- function buildHeaders(apiKey, apiKeyHeader, customHeaders, provider) {
962
- const headers = {
963
- "Content-Type": "application/json",
964
- ...customHeaders
965
- };
966
- if (apiKey) {
967
- if (apiKeyHeader === "x-api-key") {
968
- headers["x-api-key"] = apiKey;
969
- } else {
970
- headers["Authorization"] = `Bearer ${apiKey}`;
1346
+ if (Array.isArray(config?.apiKeyEnvVar)) {
1347
+ for (const key of config.apiKeyEnvVar) {
1348
+ if (process.env[key]) return process.env[key];
1349
+ }
971
1350
  }
972
1351
  }
973
- if (provider === "anthropic") {
974
- headers["anthropic-version"] = "2023-06-01";
975
- }
976
- return headers;
1352
+ return void 0;
977
1353
  }
978
1354
  var OpenAICompatibleModel = class {
979
1355
  specificationVersion = "v2";
@@ -983,9 +1359,9 @@ var OpenAICompatibleModel = class {
983
1359
  supportedUrls = {};
984
1360
  modelId;
985
1361
  provider;
986
- url;
987
- headers;
988
- apiKey;
1362
+ config;
1363
+ fullModelId;
1364
+ // Store the full model ID for gateway resolution
989
1365
  constructor(config) {
990
1366
  let parsedConfig;
991
1367
  if (typeof config === "string") {
@@ -1001,18 +1377,16 @@ var OpenAICompatibleModel = class {
1001
1377
  url: config
1002
1378
  };
1003
1379
  this.provider = "openai-compatible";
1380
+ this.fullModelId = "unknown";
1381
+ this.config = { id: "unknown", url: config };
1004
1382
  } else {
1383
+ this.fullModelId = config;
1005
1384
  const firstSlashIndex = config.indexOf("/");
1006
1385
  if (firstSlashIndex !== -1) {
1007
1386
  const provider = config.substring(0, firstSlashIndex);
1008
1387
  const modelId = config.substring(firstSlashIndex + 1);
1009
- const providerConfig2 = getProviderConfig(provider);
1010
- if (!providerConfig2) {
1011
- throw new Error(`Unknown provider: ${provider}. Use a custom URL instead.`);
1012
- }
1013
1388
  parsedConfig = {
1014
1389
  id: modelId,
1015
- url: providerConfig2.url,
1016
1390
  apiKey: resolveApiKey({ provider })
1017
1391
  };
1018
1392
  this.provider = provider;
@@ -1022,30 +1396,18 @@ var OpenAICompatibleModel = class {
1022
1396
  }
1023
1397
  } else {
1024
1398
  parsedConfig = config;
1399
+ this.fullModelId = config.id;
1025
1400
  const parsed = parseModelString(config.id);
1026
- if (!config.url && parsed.provider) {
1027
- const providerConfig2 = getProviderConfig(parsed.provider);
1028
- if (!providerConfig2) {
1029
- throw new Error(`Unknown provider: ${parsed.provider}. Please provide a URL.`);
1030
- }
1031
- parsedConfig.url = providerConfig2.url;
1401
+ this.provider = parsed.provider || "openai-compatible";
1402
+ if (parsed.provider && parsed.modelId !== config.id) {
1032
1403
  parsedConfig.id = parsed.modelId;
1033
- this.provider = parsed.provider;
1034
- } else {
1035
- this.provider = parsed.provider || "openai-compatible";
1036
1404
  }
1037
1405
  if (!parsedConfig.apiKey) {
1038
1406
  parsedConfig.apiKey = resolveApiKey({ provider: parsed.provider || void 0 });
1039
1407
  }
1040
1408
  }
1041
- if (!parsedConfig.url) {
1042
- throw new Error("URL is required for OpenAI-compatible model");
1043
- }
1044
- const providerConfig = this.provider !== "openai-compatible" ? getProviderConfig(this.provider) : void 0;
1045
1409
  this.modelId = parsedConfig.id;
1046
- this.url = parsedConfig.url;
1047
- this.apiKey = parsedConfig.apiKey;
1048
- this.headers = buildHeaders(parsedConfig.apiKey, providerConfig?.apiKeyHeader, parsedConfig.headers, this.provider);
1410
+ this.config = parsedConfig;
1049
1411
  }
1050
1412
  convertMessagesToOpenAI(messages) {
1051
1413
  return messages.map((msg) => {
@@ -1144,8 +1506,49 @@ var OpenAICompatibleModel = class {
1144
1506
  return "unknown";
1145
1507
  }
1146
1508
  }
1509
+ /**
1510
+ * Resolve URL and headers for the request
1511
+ * This is called fresh for each request to ensure we get the latest values
1512
+ * (e.g., Netlify tokens can expire and need to be refreshed)
1513
+ */
1514
+ async resolveRequestConfig() {
1515
+ const shouldUseGateway = !this.config.url;
1516
+ if (shouldUseGateway) {
1517
+ const { url, headers, resolvedModelId } = await resolveModelConfig(this.fullModelId);
1518
+ if (url === false) {
1519
+ throw new Error(`No gateway can handle model: ${this.fullModelId}`);
1520
+ }
1521
+ const finalHeaders = {
1522
+ "Content-Type": "application/json",
1523
+ ...headers,
1524
+ ...this.config.headers
1525
+ };
1526
+ return { url, headers: finalHeaders, modelId: resolvedModelId };
1527
+ } else {
1528
+ if (!this.config.url) {
1529
+ throw new Error("URL is required for OpenAI-compatible model");
1530
+ }
1531
+ const headers = {
1532
+ "Content-Type": "application/json",
1533
+ ...this.config.headers
1534
+ };
1535
+ if (this.config.apiKey) {
1536
+ const providerConfig = this.provider !== "openai-compatible" ? getProviderConfig(this.provider) : void 0;
1537
+ if (providerConfig?.apiKeyHeader === "x-api-key") {
1538
+ headers["x-api-key"] = this.config.apiKey;
1539
+ } else {
1540
+ headers["Authorization"] = `Bearer ${this.config.apiKey}`;
1541
+ }
1542
+ }
1543
+ return { url: this.config.url, headers, modelId: this.modelId };
1544
+ }
1545
+ }
1147
1546
  validateApiKey() {
1148
- if (!this.apiKey && this.provider !== "openai-compatible") {
1547
+ const willUseGateway = !this.config.url;
1548
+ if (willUseGateway) {
1549
+ return;
1550
+ }
1551
+ if (!this.config.apiKey && this.provider !== "openai-compatible") {
1149
1552
  const providerConfig = getProviderConfig(this.provider);
1150
1553
  if (providerConfig?.apiKeyEnvVar) {
1151
1554
  throw new Error(
@@ -1164,211 +1567,250 @@ var OpenAICompatibleModel = class {
1164
1567
  );
1165
1568
  }
1166
1569
  async doStream(options) {
1167
- this.validateApiKey();
1168
- const { prompt, tools, toolChoice, providerOptions } = options;
1169
- const body = {
1170
- messages: this.convertMessagesToOpenAI(prompt),
1171
- model: this.modelId,
1172
- stream: true,
1173
- ...providerOptions
1174
- };
1175
- const openAITools = this.convertToolsToOpenAI(tools);
1176
- if (openAITools) {
1177
- body.tools = openAITools;
1178
- if (toolChoice) {
1179
- body.tool_choice = toolChoice.type === "none" ? "none" : toolChoice.type === "required" ? "required" : toolChoice.type === "auto" ? "auto" : toolChoice.type === "tool" ? { type: "function", function: { name: toolChoice.toolName } } : "auto";
1180
- }
1570
+ try {
1571
+ this.validateApiKey();
1572
+ } catch (error) {
1573
+ return {
1574
+ stream: new ReadableStream({
1575
+ start(controller) {
1576
+ controller.enqueue({
1577
+ type: "error",
1578
+ error: error instanceof Error ? error.message : String(error)
1579
+ });
1580
+ }
1581
+ }),
1582
+ warnings: []
1583
+ };
1181
1584
  }
1182
- if (options.responseFormat?.type === "json") {
1183
- body.response_format = {
1184
- type: "json_schema",
1185
- json_schema: {
1186
- name: "response",
1187
- strict: true,
1188
- schema: options.responseFormat.schema
1585
+ try {
1586
+ const { url, headers, modelId: resolvedModelId } = await this.resolveRequestConfig();
1587
+ const { prompt, tools, toolChoice, providerOptions } = options;
1588
+ const body = {
1589
+ messages: this.convertMessagesToOpenAI(prompt),
1590
+ model: resolvedModelId,
1591
+ stream: true,
1592
+ ...providerOptions
1593
+ };
1594
+ const openAITools = this.convertToolsToOpenAI(tools);
1595
+ if (openAITools) {
1596
+ body.tools = openAITools;
1597
+ if (toolChoice) {
1598
+ body.tool_choice = toolChoice.type === "none" ? "none" : toolChoice.type === "required" ? "required" : toolChoice.type === "auto" ? "auto" : toolChoice.type === "tool" ? { type: "function", function: { name: toolChoice.toolName } } : "auto";
1189
1599
  }
1600
+ }
1601
+ if (options.responseFormat?.type === "json") {
1602
+ body.response_format = {
1603
+ type: "json_schema",
1604
+ json_schema: {
1605
+ name: "response",
1606
+ strict: true,
1607
+ schema: options.responseFormat.schema
1608
+ }
1609
+ };
1610
+ }
1611
+ const fetchArgs = {
1612
+ method: "POST",
1613
+ headers,
1614
+ body: JSON.stringify(body),
1615
+ signal: options.abortSignal
1190
1616
  };
1191
- }
1192
- const fetchArgs = {
1193
- method: "POST",
1194
- headers: this.headers,
1195
- body: JSON.stringify(body),
1196
- signal: options.abortSignal
1197
- };
1198
- const response = await fetch(this.url, fetchArgs);
1199
- if (!response.ok) {
1200
- const error = await response.text();
1201
- if (response.status === 401 || response.status === 403) {
1202
- const providerConfig = getProviderConfig(this.provider);
1203
- if (providerConfig?.apiKeyEnvVar) {
1204
- throw new Error(
1205
- `Authentication failed for provider "${this.provider}". Please ensure the ${providerConfig.apiKeyEnvVar} environment variable is set with a valid API key.`
1206
- );
1617
+ const response = await fetch(url, fetchArgs);
1618
+ if (!response.ok) {
1619
+ const error = await response.text();
1620
+ if (response.status === 401 || response.status === 403) {
1621
+ const providerConfig = getProviderConfig(this.provider);
1622
+ if (providerConfig?.apiKeyEnvVar) {
1623
+ throw new Error(
1624
+ `Authentication failed for provider "${this.provider}". Please ensure the ${providerConfig.apiKeyEnvVar} environment variable is set with a valid API key.`
1625
+ );
1626
+ }
1207
1627
  }
1628
+ throw new Error(`OpenAI-compatible API error: ${response.status} - ${error}`);
1208
1629
  }
1209
- throw new Error(`OpenAI-compatible API error: ${response.status} - ${error}`);
1210
- }
1211
- const reader = response.body?.getReader();
1212
- if (!reader) {
1213
- throw new Error("Response body is not readable");
1214
- }
1215
- const decoder = new TextDecoder();
1216
- let buffer = "";
1217
- let sentStart = false;
1218
- const toolCallBuffers = /* @__PURE__ */ new Map();
1219
- const mapFinishReason = this.mapFinishReason.bind(this);
1220
- const modelId = this.modelId;
1221
- let isActiveText = false;
1222
- const stream = new ReadableStream({
1223
- async start(controller) {
1224
- try {
1225
- controller.enqueue({
1226
- type: "stream-start",
1227
- warnings: []
1228
- });
1229
- while (true) {
1230
- const { done, value } = await reader.read();
1231
- if (done) {
1232
- for (const [_, toolCall] of toolCallBuffers) {
1233
- if (!toolCall.sent && toolCall.id && toolCall.name && toolCall.args) {
1234
- controller.enqueue({
1235
- type: "tool-call",
1236
- toolCallId: toolCall.id,
1237
- toolName: toolCall.name,
1238
- input: toolCall.args || "{}"
1239
- });
1240
- }
1241
- }
1242
- controller.close();
1243
- break;
1244
- }
1245
- buffer += decoder.decode(value, { stream: true });
1246
- const lines = buffer.split("\n");
1247
- buffer = lines.pop() || "";
1248
- for (const line of lines) {
1249
- if (line.trim() === "" || line.trim() === "data: [DONE]") {
1250
- continue;
1251
- }
1252
- if (line.startsWith("data: ")) {
1253
- try {
1254
- const data = JSON.parse(line.slice(6));
1255
- if (!sentStart && data.id) {
1630
+ const reader = response.body?.getReader();
1631
+ if (!reader) {
1632
+ throw new Error("Response body is not readable");
1633
+ }
1634
+ const decoder = new TextDecoder();
1635
+ let buffer = "";
1636
+ let sentStart = false;
1637
+ const toolCallBuffers = /* @__PURE__ */ new Map();
1638
+ const mapFinishReason = this.mapFinishReason.bind(this);
1639
+ const modelId = this.modelId;
1640
+ let isActiveText = false;
1641
+ const stream = new ReadableStream({
1642
+ async start(controller) {
1643
+ try {
1644
+ controller.enqueue({
1645
+ type: "stream-start",
1646
+ warnings: []
1647
+ });
1648
+ while (true) {
1649
+ const { done, value } = await reader.read();
1650
+ if (done) {
1651
+ for (const [_, toolCall] of toolCallBuffers) {
1652
+ if (!toolCall.sent && toolCall.id && toolCall.name && toolCall.args) {
1256
1653
  controller.enqueue({
1257
- type: "response-metadata",
1258
- id: data.id,
1259
- modelId: data.model || modelId,
1260
- timestamp: new Date(data.created ? data.created * 1e3 : Date.now())
1654
+ type: "tool-call",
1655
+ toolCallId: toolCall.id,
1656
+ toolName: toolCall.name,
1657
+ input: toolCall.args || "{}"
1261
1658
  });
1262
- sentStart = true;
1263
1659
  }
1264
- const choice = data.choices?.[0];
1265
- if (!choice) continue;
1266
- if (choice.delta?.content) {
1267
- if (!isActiveText) {
1268
- controller.enqueue({ type: "text-start", id: "text-1" });
1269
- isActiveText = true;
1660
+ }
1661
+ controller.close();
1662
+ break;
1663
+ }
1664
+ buffer += decoder.decode(value, { stream: true });
1665
+ const lines = buffer.split("\n");
1666
+ buffer = lines.pop() || "";
1667
+ for (const line of lines) {
1668
+ if (line.trim() === "" || line.trim() === "data: [DONE]") {
1669
+ continue;
1670
+ }
1671
+ if (line.startsWith("data: ")) {
1672
+ try {
1673
+ const data = JSON.parse(line.slice(6));
1674
+ if (!sentStart && data.id) {
1675
+ controller.enqueue({
1676
+ type: "response-metadata",
1677
+ id: data.id,
1678
+ modelId: data.model || modelId,
1679
+ timestamp: new Date(data.created ? data.created * 1e3 : Date.now())
1680
+ });
1681
+ sentStart = true;
1270
1682
  }
1271
- controller.enqueue({
1272
- type: "text-delta",
1273
- id: "text-1",
1274
- delta: choice.delta.content
1275
- });
1276
- } else if (isActiveText) {
1277
- controller.enqueue({ type: "text-end", id: "text-1" });
1278
- isActiveText = false;
1279
- }
1280
- if (choice.delta?.tool_calls) {
1281
- for (const toolCall of choice.delta.tool_calls) {
1282
- const index = toolCall.index;
1283
- if (!toolCallBuffers.has(index)) {
1284
- if (toolCall.id && toolCall.function?.name) {
1285
- controller.enqueue({
1286
- type: "tool-input-start",
1287
- id: toolCall.id,
1288
- toolName: toolCall.function.name
1289
- });
1290
- }
1291
- toolCallBuffers.set(index, {
1292
- id: toolCall.id || "",
1293
- name: toolCall.function?.name || "",
1294
- args: ""
1295
- });
1296
- }
1297
- const buffer2 = toolCallBuffers.get(index);
1298
- if (toolCall.id) {
1299
- buffer2.id = toolCall.id;
1300
- }
1301
- if (toolCall.function?.name) {
1302
- buffer2.name = toolCall.function.name;
1683
+ const choice = data.choices?.[0];
1684
+ if (!choice) continue;
1685
+ if (choice.delta?.content) {
1686
+ if (!isActiveText) {
1687
+ controller.enqueue({ type: "text-start", id: "text-1" });
1688
+ isActiveText = true;
1303
1689
  }
1304
- if (toolCall.function?.arguments) {
1305
- buffer2.args += toolCall.function.arguments;
1306
- controller.enqueue({
1307
- type: "tool-input-delta",
1308
- id: buffer2.id,
1309
- delta: toolCall.function.arguments
1310
- });
1311
- try {
1312
- JSON.parse(buffer2.args);
1313
- if (buffer2.id && buffer2.name) {
1314
- controller.enqueue({
1315
- type: "tool-input-end",
1316
- id: buffer2.id
1317
- });
1690
+ controller.enqueue({
1691
+ type: "text-delta",
1692
+ id: "text-1",
1693
+ delta: choice.delta.content
1694
+ });
1695
+ } else if (isActiveText) {
1696
+ controller.enqueue({ type: "text-end", id: "text-1" });
1697
+ isActiveText = false;
1698
+ }
1699
+ if (choice.delta?.tool_calls) {
1700
+ for (const toolCall of choice.delta.tool_calls) {
1701
+ const index = toolCall.index;
1702
+ if (!toolCallBuffers.has(index)) {
1703
+ if (toolCall.id && toolCall.function?.name) {
1318
1704
  controller.enqueue({
1319
- type: "tool-call",
1320
- toolCallId: buffer2.id,
1321
- toolName: buffer2.name,
1322
- input: buffer2.args
1323
- });
1324
- toolCallBuffers.set(index, {
1325
- id: buffer2.id,
1326
- name: buffer2.name,
1327
- args: buffer2.args,
1328
- sent: true
1705
+ type: "tool-input-start",
1706
+ id: toolCall.id,
1707
+ toolName: toolCall.function.name
1329
1708
  });
1330
1709
  }
1331
- } catch {
1710
+ toolCallBuffers.set(index, {
1711
+ id: toolCall.id || "",
1712
+ name: toolCall.function?.name || "",
1713
+ args: ""
1714
+ });
1715
+ }
1716
+ const buffer2 = toolCallBuffers.get(index);
1717
+ if (toolCall.id) {
1718
+ buffer2.id = toolCall.id;
1719
+ }
1720
+ if (toolCall.function?.name) {
1721
+ buffer2.name = toolCall.function.name;
1722
+ }
1723
+ if (toolCall.function?.arguments) {
1724
+ buffer2.args += toolCall.function.arguments;
1725
+ controller.enqueue({
1726
+ type: "tool-input-delta",
1727
+ id: buffer2.id,
1728
+ delta: toolCall.function.arguments
1729
+ });
1730
+ try {
1731
+ JSON.parse(buffer2.args);
1732
+ if (buffer2.id && buffer2.name) {
1733
+ controller.enqueue({
1734
+ type: "tool-input-end",
1735
+ id: buffer2.id
1736
+ });
1737
+ controller.enqueue({
1738
+ type: "tool-call",
1739
+ toolCallId: buffer2.id,
1740
+ toolName: buffer2.name,
1741
+ input: buffer2.args
1742
+ });
1743
+ toolCallBuffers.set(index, {
1744
+ id: buffer2.id,
1745
+ name: buffer2.name,
1746
+ args: buffer2.args,
1747
+ sent: true
1748
+ });
1749
+ }
1750
+ } catch {
1751
+ }
1332
1752
  }
1333
1753
  }
1334
1754
  }
1755
+ if (choice.finish_reason) {
1756
+ toolCallBuffers.clear();
1757
+ controller.enqueue({
1758
+ type: "finish",
1759
+ finishReason: mapFinishReason(choice.finish_reason),
1760
+ usage: data.usage ? {
1761
+ inputTokens: data.usage.prompt_tokens || 0,
1762
+ outputTokens: data.usage.completion_tokens || 0,
1763
+ totalTokens: data.usage.total_tokens || 0
1764
+ } : {
1765
+ inputTokens: 0,
1766
+ outputTokens: 0,
1767
+ totalTokens: 0
1768
+ }
1769
+ });
1770
+ }
1771
+ } catch (e) {
1772
+ console.error("Error parsing SSE data:", e);
1335
1773
  }
1336
- if (choice.finish_reason) {
1337
- toolCallBuffers.clear();
1338
- controller.enqueue({
1339
- type: "finish",
1340
- finishReason: mapFinishReason(choice.finish_reason),
1341
- usage: data.usage ? {
1342
- inputTokens: data.usage.prompt_tokens || 0,
1343
- outputTokens: data.usage.completion_tokens || 0,
1344
- totalTokens: data.usage.total_tokens || 0
1345
- } : {
1346
- inputTokens: 0,
1347
- outputTokens: 0,
1348
- totalTokens: 0
1349
- }
1350
- });
1351
- }
1352
- } catch (e) {
1353
- console.error("Error parsing SSE data:", e);
1354
1774
  }
1355
1775
  }
1356
1776
  }
1777
+ } catch (error) {
1778
+ return {
1779
+ stream: new ReadableStream({
1780
+ start(controller2) {
1781
+ controller2.enqueue({
1782
+ type: "error",
1783
+ error: error instanceof Error ? error.message : String(error)
1784
+ });
1785
+ }
1786
+ }),
1787
+ warnings: []
1788
+ };
1357
1789
  }
1358
- } catch (error) {
1359
- controller.error(error);
1360
1790
  }
1361
- }
1362
- });
1363
- return {
1364
- stream,
1365
- request: { body: JSON.stringify(body) },
1366
- response: { headers: Object.fromEntries(response.headers.entries()) },
1367
- warnings: []
1368
- };
1791
+ });
1792
+ return {
1793
+ stream,
1794
+ request: { body: JSON.stringify(body) },
1795
+ response: { headers: Object.fromEntries(response.headers.entries()) },
1796
+ warnings: []
1797
+ };
1798
+ } catch (error) {
1799
+ return {
1800
+ stream: new ReadableStream({
1801
+ start(controller) {
1802
+ controller.enqueue({
1803
+ type: "error",
1804
+ error: error instanceof Error ? error.message : String(error)
1805
+ });
1806
+ }
1807
+ }),
1808
+ warnings: []
1809
+ };
1810
+ }
1369
1811
  }
1370
1812
  };
1371
1813
 
1372
1814
  export { OpenAICompatibleModel, PROVIDER_REGISTRY, getProviderConfig, parseModelString };
1373
- //# sourceMappingURL=chunk-5M6ZTQJN.js.map
1374
- //# sourceMappingURL=chunk-5M6ZTQJN.js.map
1815
+ //# sourceMappingURL=chunk-X6PLOE2T.js.map
1816
+ //# sourceMappingURL=chunk-X6PLOE2T.js.map