e2e 0.21.1 → 0.21.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.
Files changed (133) hide show
  1. package/README.md +2 -0
  2. package/dist/.build.json +1 -1
  3. package/dist/agent/act-validation.js +1 -0
  4. package/dist/agent/act.js +7 -3
  5. package/dist/agent/action-dispatcher.js +30 -8
  6. package/dist/agent/actions.d.ts +2 -0
  7. package/dist/agent/actions.js +5 -2
  8. package/dist/agent/error.js +1 -0
  9. package/dist/agent/executor.d.ts +14 -6
  10. package/dist/agent/index.js +5 -1
  11. package/dist/agent/invocation.d.ts +3 -0
  12. package/dist/agent/model/sdk.d.ts +5 -0
  13. package/dist/agent/model/sdk.js +18 -1
  14. package/dist/agent/observation.js +1 -0
  15. package/dist/agent/primitives.js +14 -3
  16. package/dist/agent/replay.js +9 -3
  17. package/dist/agent/step-cache.d.ts +3 -2
  18. package/dist/agent/step-cache.js +7 -4
  19. package/dist/agent/tool-loop.js +4 -1
  20. package/dist/cache/context.js +1 -1
  21. package/dist/cache/recorder.d.ts +2 -1
  22. package/dist/cache/recorder.js +11 -2
  23. package/dist/cache/trace-fields.d.ts +10 -0
  24. package/dist/cache/trace-fields.js +17 -0
  25. package/dist/cache/trace.d.ts +9 -1
  26. package/dist/cache/trace.js +26 -7
  27. package/dist/cli/feedback.js +2 -1
  28. package/dist/cli/init/sibling-versions.json +1 -1
  29. package/dist/collect/select.js +12 -2
  30. package/dist/config/agent.d.ts +1 -1
  31. package/dist/config/diagnose.js +9 -3
  32. package/dist/config/esm-hooks.js +3 -2
  33. package/dist/config/resolve.js +3 -2
  34. package/dist/config/typescript.js +52 -2
  35. package/dist/engine/contract.d.ts +3 -2
  36. package/dist/engine/manifest.js +2 -2
  37. package/dist/internal/errors.js +5 -2
  38. package/dist/internal/source.js +2 -0
  39. package/dist/internal/unserved-model.d.ts +5 -0
  40. package/dist/internal/unserved-model.js +22 -0
  41. package/dist/locator/screen.js +1 -2
  42. package/dist/oauth/copilot.js +23 -5
  43. package/dist/oauth/device-code.js +35 -19
  44. package/dist/oauth/errors.d.ts +3 -0
  45. package/dist/oauth/errors.js +26 -11
  46. package/dist/oauth/providers/github-copilot.d.ts +4 -0
  47. package/dist/oauth/providers/github-copilot.js +64 -16
  48. package/dist/oauth/providers/openai.d.ts +2 -2
  49. package/dist/oauth/providers/openai.js +47 -19
  50. package/dist/oauth/providers/opencode-console.js +36 -15
  51. package/dist/oauth/providers/xai.js +18 -9
  52. package/dist/oauth/token-endpoint.d.ts +15 -6
  53. package/dist/oauth/token-endpoint.js +18 -6
  54. package/dist/report/code-frame.js +9 -3
  55. package/dist/report/failure-text.d.ts +10 -2
  56. package/dist/report/failure-text.js +24 -8
  57. package/dist/report/list-model.d.ts +13 -0
  58. package/dist/report/list-steps.d.ts +6 -1
  59. package/dist/report/list-steps.js +29 -0
  60. package/dist/report/list.d.ts +1 -0
  61. package/dist/report/list.js +16 -7
  62. package/dist/report/live-window.js +2 -1
  63. package/dist/report/markdown.js +1 -1
  64. package/dist/run/fixtures.js +2 -0
  65. package/dist/run/host-trace.d.ts +3 -2
  66. package/dist/run/host-trace.js +2 -1
  67. package/dist/run/last-run.d.ts +9 -0
  68. package/dist/run/last-run.js +28 -0
  69. package/dist/run/open-session.d.ts +3 -1
  70. package/dist/run/open-session.js +1 -1
  71. package/dist/run/runner.js +6 -2
  72. package/dist/run/sessions.js +3 -3
  73. package/dist/run/standalone-attempt.d.ts +2 -1
  74. package/dist/run/standalone-attempt.js +3 -1
  75. package/dist/run/steps.d.ts +3 -1
  76. package/dist/run/units.d.ts +8 -0
  77. package/dist/run/units.js +14 -0
  78. package/dist/run/worker-models.d.ts +2 -0
  79. package/dist/run/worker-models.js +7 -0
  80. package/dist/types.d.ts +2 -2
  81. package/docs/authentication.mdx +26 -23
  82. package/docs/browser.mdx +7 -4
  83. package/docs/bug-bash.mdx +2 -2
  84. package/docs/cache.mdx +6 -1
  85. package/docs/ci/bitrise.mdx +1 -1
  86. package/docs/ci/codemagic.mdx +2 -2
  87. package/docs/ci/eas-workflows.mdx +1 -1
  88. package/docs/coding-agents.mdx +7 -35
  89. package/docs/debugging.mdx +24 -36
  90. package/docs/executors.mdx +1 -1
  91. package/docs/github.mdx +2 -1
  92. package/docs/integrations/eas.mdx +1 -1
  93. package/docs/integrations/index.mdx +6 -0
  94. package/docs/integrations/lightpanda.mdx +192 -0
  95. package/docs/integrations/testmu.mdx +152 -0
  96. package/docs/mcp.mdx +123 -0
  97. package/docs/migrate/detox.mdx +1 -1
  98. package/docs/migrate/maestro.mdx +101 -105
  99. package/docs/migrate/playwright.mdx +65 -70
  100. package/docs/mobile.mdx +18 -3
  101. package/docs/models.mdx +4 -2
  102. package/docs/quickstart.mdx +7 -0
  103. package/docs/reference/agent.mdx +369 -277
  104. package/docs/reference/app.mdx +141 -32
  105. package/docs/reference/cli.mdx +674 -558
  106. package/docs/reference/config.mdx +1406 -752
  107. package/docs/reference/engine.mdx +1062 -256
  108. package/docs/reference/environment.mdx +156 -84
  109. package/docs/reference/errors.mdx +106 -72
  110. package/docs/reference/expect.mdx +752 -372
  111. package/docs/reference/mcp.mdx +366 -141
  112. package/docs/reference/mobile.mdx +844 -403
  113. package/docs/reference/reporters.mdx +312 -106
  114. package/docs/reference/runner.mdx +373 -174
  115. package/docs/reference/screen.mdx +931 -398
  116. package/docs/reference/security.mdx +106 -40
  117. package/docs/reference/test.mdx +626 -273
  118. package/docs/reference/web.mdx +956 -533
  119. package/docs/security.mdx +6 -5
  120. package/docs/snippets/model-provider.jsx +763 -0
  121. package/docs/snippets/setup-prompt-card.jsx +22 -0
  122. package/docs/snippets/show-more.jsx +22 -0
  123. package/docs/snippets/video-card.jsx +34 -0
  124. package/docs/snippets/video.jsx +25 -0
  125. package/docs/subscriptions.mdx +10 -3
  126. package/docs/telemetry.mdx +39 -39
  127. package/package.json +3 -2
  128. package/schema/report-v1.schema.json +6 -0
  129. package/skills/e2e/references/agent.md +8 -3
  130. package/skills/e2e/references/debugging.md +1 -1
  131. package/skills/e2e/references/mcp.md +1 -1
  132. package/skills/e2e/references/setup.md +12 -3
  133. package/skills/e2e/references/writing-tests.md +1 -1
@@ -0,0 +1,763 @@
1
+ /**
2
+ * One part of the provider setup on the Models and Quickstart pages: `show`
3
+ * is `select`, `install`, `env`, `config` (a whole web config), or `model`
4
+ * (the import and model alone, for any target). All parts share one selection.
5
+ *
6
+ * Mintlify evaluates each snippet export alone, so exports share no module
7
+ * scope. For this reason, one component takes `show`, and the selection is a
8
+ * store on `globalThis` read with `React.useSyncExternalStore`. The server
9
+ * snapshot is the default, and only event handlers write the store.
10
+ *
11
+ * The list comes from https://ai-sdk.dev/providers. It excludes providers
12
+ * without a language model, models without tool calls (Perplexity,
13
+ * llama.cpp, QuiverAI), agent CLIs with their own tool loop (Claude Code,
14
+ * Codex CLI, Gemini CLI, OpenCode, ACP, A2A), browser- and device-only
15
+ * runtimes, packages on the v1 model specification, and packages that do not
16
+ * load as ESM or do not typecheck (Apertis 3.0.0, Requesty 3.6.2).
17
+ * `readsAtLoad` marks providers that throw at construction when their
18
+ * variables are missing.
19
+ */
20
+ export const ModelProvider = ({ show }) => {
21
+ const providers = [
22
+ {
23
+ id: 'gateway',
24
+ name: 'Vercel AI Gateway',
25
+ group: 'AI SDK',
26
+ packages: [],
27
+ code: "import { gateway } from 'ai';",
28
+ model: "gateway('openai/gpt-6-luna-fast')",
29
+ env: ['AI_GATEWAY_API_KEY'],
30
+ note: 'You can use a Vercel OIDC token from a linked project instead of a key.',
31
+ docs: 'https://ai-sdk.dev/providers/ai-sdk-providers/ai-gateway',
32
+ },
33
+ {
34
+ id: 'openai',
35
+ name: 'OpenAI',
36
+ group: 'AI SDK',
37
+ packages: ['@ai-sdk/openai'],
38
+ code: "import { openai } from '@ai-sdk/openai';",
39
+ model: "openai('gpt-6-luna')",
40
+ env: ['OPENAI_API_KEY'],
41
+ docs: 'https://ai-sdk.dev/providers/ai-sdk-providers/openai',
42
+ },
43
+ {
44
+ id: 'anthropic',
45
+ name: 'Anthropic',
46
+ group: 'AI SDK',
47
+ packages: ['@ai-sdk/anthropic'],
48
+ code: "import { anthropic } from '@ai-sdk/anthropic';",
49
+ model: "anthropic('claude-sonnet-5-5')",
50
+ env: ['ANTHROPIC_API_KEY'],
51
+ docs: 'https://ai-sdk.dev/providers/ai-sdk-providers/anthropic',
52
+ },
53
+ {
54
+ id: 'google',
55
+ name: 'Google Generative AI',
56
+ group: 'AI SDK',
57
+ packages: ['@ai-sdk/google'],
58
+ code: "import { google } from '@ai-sdk/google';",
59
+ model: "google('gemini-3.8-flash')",
60
+ env: ['GOOGLE_GENERATIVE_AI_API_KEY'],
61
+ docs: 'https://ai-sdk.dev/providers/ai-sdk-providers/google',
62
+ },
63
+ {
64
+ id: 'google-vertex',
65
+ name: 'Google Vertex AI',
66
+ group: 'AI SDK',
67
+ packages: ['@ai-sdk/google-vertex'],
68
+ code: "import { googleVertex } from '@ai-sdk/google-vertex';",
69
+ model: "googleVertex('gemini-3.8-flash')",
70
+ env: ['GOOGLE_VERTEX_PROJECT', 'GOOGLE_VERTEX_LOCATION', 'GOOGLE_APPLICATION_CREDENTIALS'],
71
+ docs: 'https://ai-sdk.dev/providers/ai-sdk-providers/google-vertex',
72
+ readsAtLoad: true,
73
+ },
74
+ {
75
+ id: 'azure',
76
+ name: 'Azure OpenAI',
77
+ group: 'AI SDK',
78
+ packages: ['@ai-sdk/azure'],
79
+ code: "import { azure } from '@ai-sdk/azure';",
80
+ model: "azure('your-deployment-name')",
81
+ env: ['AZURE_RESOURCE_NAME', 'AZURE_API_KEY'],
82
+ docs: 'https://ai-sdk.dev/providers/ai-sdk-providers/azure',
83
+ },
84
+ {
85
+ id: 'amazon-bedrock',
86
+ name: 'Amazon Bedrock',
87
+ group: 'AI SDK',
88
+ packages: ['@ai-sdk/amazon-bedrock'],
89
+ code: "import { amazonBedrock } from '@ai-sdk/amazon-bedrock';",
90
+ model: "amazonBedrock('eu.anthropic.claude-sonnet-4-6')",
91
+ env: ['AWS_REGION', 'AWS_BEARER_TOKEN_BEDROCK'],
92
+ note: 'You can use AWS_ACCESS_KEY_ID and AWS_SECRET_ACCESS_KEY instead of the bearer token. The eu. model prefix needs an EU region.',
93
+ docs: 'https://ai-sdk.dev/providers/ai-sdk-providers/amazon-bedrock',
94
+ },
95
+ {
96
+ id: 'anthropic-aws',
97
+ name: 'Claude Platform on AWS',
98
+ group: 'AI SDK',
99
+ packages: ['@ai-sdk/anthropic-aws'],
100
+ code: "import { anthropicAws } from '@ai-sdk/anthropic-aws';",
101
+ model: "anthropicAws('claude-sonnet-5-5')",
102
+ env: ['AWS_REGION', 'ANTHROPIC_AWS_WORKSPACE_ID', 'ANTHROPIC_AWS_API_KEY'],
103
+ note: 'You can use AWS credentials instead of the API key.',
104
+ docs: 'https://ai-sdk.dev/providers/ai-sdk-providers/anthropic-aws',
105
+ readsAtLoad: true,
106
+ },
107
+ {
108
+ id: 'xai',
109
+ name: 'xAI Grok',
110
+ group: 'AI SDK',
111
+ packages: ['@ai-sdk/xai'],
112
+ code: "import { xai } from '@ai-sdk/xai';",
113
+ model: "xai('grok-4.7')",
114
+ env: ['XAI_API_KEY'],
115
+ docs: 'https://ai-sdk.dev/providers/ai-sdk-providers/xai',
116
+ },
117
+ {
118
+ id: 'mistral',
119
+ name: 'Mistral AI',
120
+ group: 'AI SDK',
121
+ packages: ['@ai-sdk/mistral'],
122
+ code: "import { mistral } from '@ai-sdk/mistral';",
123
+ model: "mistral('mistral-medium-3.5')",
124
+ env: ['MISTRAL_API_KEY'],
125
+ docs: 'https://ai-sdk.dev/providers/ai-sdk-providers/mistral',
126
+ },
127
+ {
128
+ id: 'deepseek',
129
+ name: 'DeepSeek',
130
+ group: 'AI SDK',
131
+ packages: ['@ai-sdk/deepseek'],
132
+ code: "import { deepSeek } from '@ai-sdk/deepseek';",
133
+ model: "deepSeek('deepseek-v4-flash')",
134
+ env: ['DEEPSEEK_API_KEY'],
135
+ docs: 'https://ai-sdk.dev/providers/ai-sdk-providers/deepseek',
136
+ },
137
+ {
138
+ id: 'moonshotai',
139
+ name: 'Moonshot AI',
140
+ group: 'AI SDK',
141
+ packages: ['@ai-sdk/moonshotai'],
142
+ code: "import { moonshotai } from '@ai-sdk/moonshotai';",
143
+ model: "moonshotai('kimi-k3')",
144
+ env: ['MOONSHOT_API_KEY'],
145
+ docs: 'https://ai-sdk.dev/providers/ai-sdk-providers/moonshotai',
146
+ },
147
+ {
148
+ id: 'alibaba',
149
+ name: 'Alibaba',
150
+ group: 'AI SDK',
151
+ packages: ['@ai-sdk/alibaba'],
152
+ code: "import { alibaba } from '@ai-sdk/alibaba';",
153
+ model: "alibaba('qwen3-max')",
154
+ env: ['ALIBABA_API_KEY'],
155
+ docs: 'https://ai-sdk.dev/providers/ai-sdk-providers/alibaba',
156
+ },
157
+ {
158
+ id: 'zai',
159
+ name: 'Z.AI',
160
+ group: 'AI SDK',
161
+ packages: ['@ai-sdk/zai'],
162
+ code: "import { zai } from '@ai-sdk/zai';",
163
+ model: "zai('glm-5.3')",
164
+ env: ['ZAI_API_KEY'],
165
+ docs: 'https://ai-sdk.dev/providers/ai-sdk-providers/zai',
166
+ },
167
+ {
168
+ id: 'minimax',
169
+ name: 'MiniMax',
170
+ group: 'AI SDK',
171
+ packages: ['@ai-sdk/minimax'],
172
+ code: "import { minimax } from '@ai-sdk/minimax';",
173
+ model: "minimax('minimax-m3')",
174
+ env: ['MINIMAX_API_KEY'],
175
+ docs: 'https://ai-sdk.dev/providers/ai-sdk-providers/minimax',
176
+ },
177
+ {
178
+ id: 'groq',
179
+ name: 'Groq',
180
+ group: 'AI SDK',
181
+ packages: ['@ai-sdk/groq'],
182
+ code: "import { groq } from '@ai-sdk/groq';",
183
+ model: "groq('meta-llama/llama-4-scout-17b-16e-instruct')",
184
+ env: ['GROQ_API_KEY'],
185
+ docs: 'https://ai-sdk.dev/providers/ai-sdk-providers/groq',
186
+ },
187
+ {
188
+ id: 'cerebras',
189
+ name: 'Cerebras',
190
+ group: 'AI SDK',
191
+ packages: ['@ai-sdk/cerebras'],
192
+ code: "import { cerebras } from '@ai-sdk/cerebras';",
193
+ model: "cerebras('gemma-4-31b')",
194
+ env: ['CEREBRAS_API_KEY'],
195
+ docs: 'https://ai-sdk.dev/providers/ai-sdk-providers/cerebras',
196
+ },
197
+ {
198
+ id: 'fireworks',
199
+ name: 'Fireworks',
200
+ group: 'AI SDK',
201
+ packages: ['@ai-sdk/fireworks'],
202
+ code: "import { fireworks } from '@ai-sdk/fireworks';",
203
+ model: "fireworks('accounts/fireworks/models/kimi-k2p6')",
204
+ env: ['FIREWORKS_API_KEY'],
205
+ docs: 'https://ai-sdk.dev/providers/ai-sdk-providers/fireworks',
206
+ },
207
+ {
208
+ id: 'togetherai',
209
+ name: 'Together.ai',
210
+ group: 'AI SDK',
211
+ packages: ['@ai-sdk/togetherai'],
212
+ code: "import { togetherai } from '@ai-sdk/togetherai';",
213
+ model: "togetherai('mistralai/Mixtral-8x22B-Instruct-v0.1')",
214
+ env: ['TOGETHER_API_KEY'],
215
+ docs: 'https://ai-sdk.dev/providers/ai-sdk-providers/togetherai',
216
+ },
217
+ {
218
+ id: 'deepinfra',
219
+ name: 'DeepInfra',
220
+ group: 'AI SDK',
221
+ packages: ['@ai-sdk/deepinfra'],
222
+ code: "import { deepInfra } from '@ai-sdk/deepinfra';",
223
+ model: "deepInfra('meta-llama/Llama-3.3-70B-Instruct')",
224
+ env: ['DEEPINFRA_API_KEY'],
225
+ docs: 'https://ai-sdk.dev/providers/ai-sdk-providers/deepinfra',
226
+ },
227
+ {
228
+ id: 'cohere',
229
+ name: 'Cohere',
230
+ group: 'AI SDK',
231
+ packages: ['@ai-sdk/cohere'],
232
+ code: "import { cohere } from '@ai-sdk/cohere';",
233
+ model: "cohere('command-a-03-2025')",
234
+ env: ['COHERE_API_KEY'],
235
+ docs: 'https://ai-sdk.dev/providers/ai-sdk-providers/cohere',
236
+ },
237
+ {
238
+ id: 'huggingface',
239
+ name: 'Hugging Face',
240
+ group: 'AI SDK',
241
+ packages: ['@ai-sdk/huggingface'],
242
+ code: "import { huggingFace } from '@ai-sdk/huggingface';",
243
+ model: "huggingFace('Qwen/Qwen2.5-VL-7B-Instruct')",
244
+ env: ['HUGGINGFACE_API_KEY'],
245
+ docs: 'https://ai-sdk.dev/providers/ai-sdk-providers/huggingface',
246
+ },
247
+ {
248
+ id: 'baseten',
249
+ name: 'Baseten',
250
+ group: 'AI SDK',
251
+ packages: ['@ai-sdk/baseten'],
252
+ code: "import { baseten } from '@ai-sdk/baseten';",
253
+ model: "baseten('moonshotai/Kimi-K2-Instruct-0905')",
254
+ env: ['BASETEN_API_KEY'],
255
+ docs: 'https://ai-sdk.dev/providers/ai-sdk-providers/baseten',
256
+ },
257
+ {
258
+ id: 'gmicloud',
259
+ name: 'GMI Cloud',
260
+ group: 'AI SDK',
261
+ packages: ['@ai-sdk/gmicloud'],
262
+ code: "import { gmicloud } from '@ai-sdk/gmicloud';",
263
+ model: "gmicloud('deepseek-ai/DeepSeek-V4-Flash-0731')",
264
+ env: ['GMI_CLOUD_APIKEY'],
265
+ docs: 'https://ai-sdk.dev/providers/ai-sdk-providers/gmicloud',
266
+ },
267
+ {
268
+ id: 'open-responses',
269
+ name: 'Open Responses endpoint',
270
+ group: 'AI SDK',
271
+ packages: ['@ai-sdk/open-responses'],
272
+ code: `import { createOpenResponses } from '@ai-sdk/open-responses';
273
+
274
+ const local = createOpenResponses({
275
+ name: 'local',
276
+ url: 'http://localhost:1234/v1/responses',
277
+ });`,
278
+ model: "local('your-model-id')",
279
+ env: [],
280
+ note: 'Use a server that has the Responses API. Add apiKey if the server needs a key.',
281
+ docs: 'https://ai-sdk.dev/providers/ai-sdk-providers/open-responses',
282
+ },
283
+ {
284
+ id: 'openrouter',
285
+ name: 'OpenRouter',
286
+ group: 'Community',
287
+ packages: ['@openrouter/ai-sdk-provider'],
288
+ code: "import { openrouter } from '@openrouter/ai-sdk-provider';",
289
+ model: "openrouter('openai/gpt-6-luna-fast')",
290
+ env: ['OPENROUTER_API_KEY'],
291
+ docs: 'https://ai-sdk.dev/providers/community-providers/openrouter',
292
+ },
293
+ {
294
+ id: 'ollama',
295
+ name: 'Ollama',
296
+ group: 'Community',
297
+ packages: ['ollama-ai-provider-v2'],
298
+ code: "import { ollama } from 'ollama-ai-provider-v2';",
299
+ model: "ollama('qwen3:4b')",
300
+ env: [],
301
+ note: 'Start Ollama on its default port.',
302
+ docs: 'https://ai-sdk.dev/providers/community-providers/ollama',
303
+ },
304
+ {
305
+ id: 'helicone',
306
+ name: 'Helicone',
307
+ group: 'Community',
308
+ packages: ['@helicone/ai-sdk-provider'],
309
+ code: `import { createHelicone } from '@helicone/ai-sdk-provider';
310
+
311
+ const helicone = createHelicone({ apiKey: process.env.HELICONE_API_KEY });`,
312
+ model: "helicone('claude-4.5-haiku')",
313
+ env: ['HELICONE_API_KEY'],
314
+ docs: 'https://ai-sdk.dev/providers/community-providers/helicone',
315
+ },
316
+ {
317
+ id: 'neon',
318
+ name: 'Neon AI Gateway',
319
+ group: 'Community',
320
+ packages: ['@neon/ai-sdk-provider'],
321
+ code: "import { neon } from '@neon/ai-sdk-provider';",
322
+ model: "neon('gpt-5-mini')",
323
+ env: ['NEON_AI_GATEWAY_BASE_URL', 'NEON_AI_GATEWAY_TOKEN'],
324
+ docs: 'https://ai-sdk.dev/providers/community-providers/neon-ai-gateway',
325
+ },
326
+ {
327
+ id: 'aihubmix',
328
+ name: 'AIHubMix',
329
+ group: 'Community',
330
+ packages: ['@aihubmix/ai-sdk-provider'],
331
+ code: "import { aihubmix } from '@aihubmix/ai-sdk-provider';",
332
+ model: "aihubmix('gemini-2.5-flash')",
333
+ env: ['AIHUBMIX_API_KEY'],
334
+ docs: 'https://ai-sdk.dev/providers/community-providers/aihubmix',
335
+ readsAtLoad: true,
336
+ },
337
+ {
338
+ id: 'aimlapi',
339
+ name: 'AI/ML API',
340
+ group: 'Community',
341
+ packages: ['@ai-ml.api/aimlapi-vercel-ai'],
342
+ code: "import { aimlapi } from '@ai-ml.api/aimlapi-vercel-ai';",
343
+ model: "aimlapi('gpt-4o')",
344
+ env: ['AIMLAPI_API_KEY'],
345
+ docs: 'https://ai-sdk.dev/providers/community-providers/aimlapi',
346
+ },
347
+ {
348
+ id: 'cencori',
349
+ name: 'Cencori',
350
+ group: 'Community',
351
+ packages: ['cencori'],
352
+ code: "import { cencori } from 'cencori/vercel';",
353
+ model: "cencori('gpt-4o')",
354
+ env: ['CENCORI_API_KEY'],
355
+ docs: 'https://ai-sdk.dev/providers/community-providers/cencori',
356
+ readsAtLoad: true,
357
+ },
358
+ {
359
+ id: 'crusoe',
360
+ name: 'Crusoe',
361
+ group: 'Community',
362
+ packages: ['crusoe-ai-provider'],
363
+ code: "import { crusoe } from 'crusoe-ai-provider';",
364
+ model: "crusoe('zai/GLM-5.2')",
365
+ env: ['CRUSOE_API_KEY'],
366
+ docs: 'https://ai-sdk.dev/providers/community-providers/crusoe',
367
+ },
368
+ {
369
+ id: 'friendliai',
370
+ name: 'FriendliAI',
371
+ group: 'Community',
372
+ packages: ['@friendliai/ai-provider'],
373
+ code: "import { friendli } from '@friendliai/ai-provider';",
374
+ model: "friendli('meta-llama-3.3-70b-instruct')",
375
+ env: ['FRIENDLI_TOKEN'],
376
+ docs: 'https://ai-sdk.dev/providers/community-providers/friendliai',
377
+ },
378
+ {
379
+ id: 'runpod',
380
+ name: 'Runpod',
381
+ group: 'Community',
382
+ packages: ['@runpod/ai-sdk-provider'],
383
+ code: "import { runpod } from '@runpod/ai-sdk-provider';",
384
+ model: "runpod('qwen/qwen3-32b-awq')",
385
+ env: ['RUNPOD_API_KEY'],
386
+ docs: 'https://ai-sdk.dev/providers/community-providers/runpod',
387
+ },
388
+ {
389
+ id: 'sambanova',
390
+ name: 'SambaNova',
391
+ group: 'Community',
392
+ packages: ['sambanova-ai-provider'],
393
+ code: "import { sambanova } from 'sambanova-ai-provider';",
394
+ model: "sambanova('Meta-Llama-3.1-70B-Instruct')",
395
+ env: ['SAMBANOVA_API_KEY'],
396
+ docs: 'https://ai-sdk.dev/providers/community-providers/sambanova',
397
+ },
398
+ {
399
+ id: 'telnyx',
400
+ name: 'Telnyx',
401
+ group: 'Community',
402
+ packages: ['@telnyx/ai-sdk-provider'],
403
+ code: "import { telnyx } from '@telnyx/ai-sdk-provider';",
404
+ model: "telnyx('Qwen/Qwen3-235B-A22B')",
405
+ env: ['TELNYX_API_KEY'],
406
+ docs: 'https://ai-sdk.dev/providers/community-providers/telnyx',
407
+ readsAtLoad: true,
408
+ },
409
+ {
410
+ id: 'zhipu',
411
+ name: 'Zhipu AI (BigModel)',
412
+ group: 'Community',
413
+ packages: ['zhipu-ai-provider'],
414
+ code: "import { zhipu } from 'zhipu-ai-provider';",
415
+ model: "zhipu('glm-4-plus')",
416
+ env: ['ZHIPU_API_KEY'],
417
+ docs: 'https://ai-sdk.dev/providers/community-providers/zhipu',
418
+ },
419
+ {
420
+ id: 'sap-ai',
421
+ name: 'SAP AI Core',
422
+ group: 'Community',
423
+ packages: ['@jerome-benoit/sap-ai-provider'],
424
+ code: "import { sapai } from '@jerome-benoit/sap-ai-provider';",
425
+ model: "sapai('gpt-4.1')",
426
+ env: ['AICORE_SERVICE_KEY'],
427
+ docs: 'https://ai-sdk.dev/providers/community-providers/sap-ai',
428
+ },
429
+ {
430
+ id: 'azure-ai',
431
+ name: 'Azure AI Foundry',
432
+ group: 'Community',
433
+ packages: ['@quail-ai/azure-ai-provider'],
434
+ code: `import { createAzure } from '@quail-ai/azure-ai-provider';
435
+
436
+ const azure = createAzure({
437
+ endpoint: process.env.AZURE_API_ENDPOINT,
438
+ apiKey: process.env.AZURE_API_KEY,
439
+ });`,
440
+ model: "azure('your-deployment-name')",
441
+ env: ['AZURE_API_ENDPOINT', 'AZURE_API_KEY'],
442
+ docs: 'https://ai-sdk.dev/providers/community-providers/azure-ai',
443
+ readsAtLoad: true,
444
+ },
445
+ {
446
+ id: 'interfaze',
447
+ name: 'Interfaze',
448
+ group: 'Community',
449
+ packages: ['@interfaze-ai/ai-sdk'],
450
+ code: "import { interfaze } from '@interfaze-ai/ai-sdk';",
451
+ model: "interfaze('interfaze-beta')",
452
+ env: ['INTERFAZE_API_KEY'],
453
+ docs: 'https://ai-sdk.dev/providers/community-providers/interfaze',
454
+ },
455
+ {
456
+ id: 'ollm',
457
+ name: 'OLLM',
458
+ group: 'Community',
459
+ packages: ['@ofoundation/ollm'],
460
+ code: `import { createOLLM } from '@ofoundation/ollm';
461
+
462
+ const ollm = createOLLM({ apiKey: process.env.OLLM_API_KEY });`,
463
+ model: "ollm.chatModel('near/GLM-4.6')",
464
+ env: ['OLLM_API_KEY'],
465
+ docs: 'https://ai-sdk.dev/providers/community-providers/ollm',
466
+ },
467
+ {
468
+ id: 'qvac',
469
+ name: 'QVAC',
470
+ group: 'Community',
471
+ packages: ['@qvac/ai-sdk-provider'],
472
+ code: `import { createQvac } from '@qvac/ai-sdk-provider';
473
+
474
+ const qvac = createQvac({
475
+ baseURL: 'http://127.0.0.1:11434/v1',
476
+ apiKey: 'qvac',
477
+ });`,
478
+ model: "qvac('qwen3.5-0.8b')",
479
+ env: [],
480
+ note: 'Start qvac serve. Set baseURL to its port.',
481
+ docs: 'https://ai-sdk.dev/providers/community-providers/qvac',
482
+ },
483
+ {
484
+ id: 'openai-compatible',
485
+ name: 'Any OpenAI-compatible endpoint',
486
+ group: 'OpenAI-compatible',
487
+ packages: ['@ai-sdk/openai-compatible'],
488
+ code: `import { createOpenAICompatible } from '@ai-sdk/openai-compatible';
489
+
490
+ const local = createOpenAICompatible({
491
+ name: 'local',
492
+ baseURL: 'http://127.0.0.1:11434/v1',
493
+ // apiKey: process.env.LLM_API_KEY,
494
+ });`,
495
+ model: "local.chatModel('your-model-id')",
496
+ env: [],
497
+ note: 'Use vLLM, llama-server, LiteLLM, or a different server with /v1/chat/completions.',
498
+ docs: 'https://ai-sdk.dev/providers/openai-compatible-providers',
499
+ },
500
+ {
501
+ id: 'lmstudio',
502
+ name: 'LM Studio',
503
+ group: 'OpenAI-compatible',
504
+ packages: ['@ai-sdk/openai-compatible'],
505
+ code: `import { createOpenAICompatible } from '@ai-sdk/openai-compatible';
506
+
507
+ const lmstudio = createOpenAICompatible({
508
+ name: 'lmstudio',
509
+ baseURL: 'http://localhost:1234/v1',
510
+ });`,
511
+ model: "lmstudio('llama-3.2-1b')",
512
+ env: [],
513
+ docs: 'https://ai-sdk.dev/providers/openai-compatible-providers/lmstudio',
514
+ },
515
+ {
516
+ id: 'nim',
517
+ name: 'NVIDIA NIM',
518
+ group: 'OpenAI-compatible',
519
+ packages: ['@ai-sdk/openai-compatible'],
520
+ code: `import { createOpenAICompatible } from '@ai-sdk/openai-compatible';
521
+
522
+ const nim = createOpenAICompatible({
523
+ name: 'nim',
524
+ baseURL: 'https://integrate.api.nvidia.com/v1',
525
+ headers: { Authorization: \`Bearer \${process.env.NIM_API_KEY}\` },
526
+ });`,
527
+ model: "nim.chatModel('meta/llama-3.3-70b-instruct')",
528
+ env: ['NIM_API_KEY'],
529
+ docs: 'https://ai-sdk.dev/providers/openai-compatible-providers/nim',
530
+ },
531
+ {
532
+ id: 'heroku',
533
+ name: 'Heroku',
534
+ group: 'OpenAI-compatible',
535
+ packages: ['@ai-sdk/openai-compatible'],
536
+ code: `import { createOpenAICompatible } from '@ai-sdk/openai-compatible';
537
+
538
+ const heroku = createOpenAICompatible({
539
+ name: 'heroku',
540
+ baseURL: process.env.INFERENCE_URL + '/v1',
541
+ apiKey: process.env.INFERENCE_KEY,
542
+ });`,
543
+ model: "heroku('claude-3-5-haiku')",
544
+ env: ['INFERENCE_URL', 'INFERENCE_KEY'],
545
+ docs: 'https://ai-sdk.dev/providers/openai-compatible-providers/heroku',
546
+ },
547
+ {
548
+ id: 'clarifai',
549
+ name: 'Clarifai',
550
+ group: 'OpenAI-compatible',
551
+ packages: ['@ai-sdk/openai-compatible'],
552
+ code: `import { createOpenAICompatible } from '@ai-sdk/openai-compatible';
553
+
554
+ const clarifai = createOpenAICompatible({
555
+ name: 'clarifai',
556
+ baseURL: 'https://api.clarifai.com/v2/ext/openai/v1',
557
+ apiKey: process.env.CLARIFAI_PAT,
558
+ });`,
559
+ model: "clarifai.chatModel('https://clarifai.com/deepseek-ai/deepseek-chat/models/DeepSeek-R1-0528-Qwen3-8B')",
560
+ env: ['CLARIFAI_PAT'],
561
+ docs: 'https://ai-sdk.dev/providers/openai-compatible-providers/clarifai',
562
+ },
563
+ {
564
+ id: 'nearai',
565
+ name: 'NEAR AI Cloud',
566
+ group: 'OpenAI-compatible',
567
+ packages: ['@ai-sdk/openai-compatible'],
568
+ code: `import { createOpenAICompatible } from '@ai-sdk/openai-compatible';
569
+
570
+ const nearai = createOpenAICompatible({
571
+ name: 'nearai',
572
+ baseURL: 'https://cloud-api.near.ai/v1',
573
+ apiKey: process.env.NEARAI_API_KEY,
574
+ });`,
575
+ model: "nearai('zai-org/GLM-5.1-FP8')",
576
+ env: ['NEARAI_API_KEY'],
577
+ docs: 'https://ai-sdk.dev/providers/openai-compatible-providers/nearai',
578
+ },
579
+ {
580
+ id: 'modelrush',
581
+ name: 'ModelRush',
582
+ group: 'OpenAI-compatible',
583
+ packages: ['@ai-sdk/openai-compatible'],
584
+ code: `import { createOpenAICompatible } from '@ai-sdk/openai-compatible';
585
+
586
+ const modelrush = createOpenAICompatible({
587
+ name: 'modelrush',
588
+ baseURL: 'https://api.modelrush.ai/v1',
589
+ apiKey: process.env.MODELRUSH_API_KEY,
590
+ });`,
591
+ model: "modelrush.chatModel('modelrush/deepseek-v4-flash-0731')",
592
+ env: ['MODELRUSH_API_KEY'],
593
+ docs: 'https://ai-sdk.dev/providers/openai-compatible-providers/modelrush',
594
+ },
595
+ {
596
+ id: 'cheaper-inference',
597
+ name: 'Cheaper Inference',
598
+ group: 'OpenAI-compatible',
599
+ packages: ['@ai-sdk/openai-compatible'],
600
+ code: `import { createOpenAICompatible } from '@ai-sdk/openai-compatible';
601
+
602
+ const cheaperInference = createOpenAICompatible({
603
+ name: 'cheaper-inference',
604
+ baseURL: 'https://api.cheaperinference.com/v1',
605
+ apiKey: process.env.CHEAPER_INFERENCE_API_KEY,
606
+ });`,
607
+ model: "cheaperInference('gpt-5.4')",
608
+ env: ['CHEAPER_INFERENCE_API_KEY'],
609
+ docs: 'https://ai-sdk.dev/providers/openai-compatible-providers/cheaper-inference',
610
+ },
611
+ ];
612
+ const groups = [
613
+ ['AI SDK', 'AI SDK providers'],
614
+ ['Community', 'Community providers'],
615
+ ['OpenAI-compatible', 'OpenAI-compatible endpoints'],
616
+ ];
617
+ const managers = [
618
+ ['npm', 'npm install -D'],
619
+ ['pnpm', 'pnpm add -D'],
620
+ ['bun', 'bun add -d'],
621
+ ];
622
+ const initial = { providerId: providers[0].id, manager: 'npm' };
623
+
624
+ const store = (globalThis[Symbol.for('e2e.docs.modelProvider')] ??= (() => {
625
+ const listeners = new Set();
626
+ const self = {
627
+ state: initial,
628
+ subscribe(listener) {
629
+ listeners.add(listener);
630
+ return () => listeners.delete(listener);
631
+ },
632
+ update(patch) {
633
+ self.state = { ...self.state, ...patch };
634
+ for (const listener of listeners) listener();
635
+ },
636
+ };
637
+ return self;
638
+ })());
639
+ const state = React.useSyncExternalStore(
640
+ store.subscribe,
641
+ () => store.state,
642
+ () => initial,
643
+ );
644
+
645
+ const provider = providers.find((p) => p.id === state.providerId);
646
+ const install = [
647
+ managers.find(([name]) => name === state.manager)[1],
648
+ 'ai',
649
+ ...provider.packages,
650
+ ].join(' ');
651
+ const env = provider.env.map((name) => `export ${name}=...`).join('\n');
652
+ const config = `import type { E2EConfig } from 'e2e';
653
+ import { web } from '@e2e-dev/web';
654
+ ${provider.code}
655
+
656
+ export default {
657
+ targets: [{ engine: web(), app: { url: 'http://localhost:3000' } }],
658
+ agents: { default: { model: ${provider.model} } },
659
+ } satisfies E2EConfig;`;
660
+ const model = `${provider.code}
661
+
662
+ const agent = { model: ${provider.model} };`;
663
+
664
+ /** Mintlify's own code block: Shiki highlighting in the site theme, and its copy button. */
665
+ const code = (text, language) => <CodeBlock language={language}>{text}</CodeBlock>;
666
+
667
+ const part = (title, body, aside = null) => (
668
+ <div className="provider-part">
669
+ <div className="provider-part-header">
670
+ <span>
671
+ {title}
672
+ <span className="provider-part-provider"> · {provider.name}</span>
673
+ </span>
674
+ {aside}
675
+ </div>
676
+ {body}
677
+ </div>
678
+ );
679
+
680
+ if (show === 'select') {
681
+ return (
682
+ <div className="provider-part provider-part-select">
683
+ <div className="provider-part-header">
684
+ <label htmlFor="provider-select">Provider</label>
685
+ <select
686
+ id="provider-select"
687
+ value={provider.id}
688
+ onChange={(event) => store.update({ providerId: event.target.value })}
689
+ >
690
+ {groups.map(([group, label]) => (
691
+ <optgroup key={group} label={label}>
692
+ {providers
693
+ .filter((p) => p.group === group)
694
+ .map((p) => (
695
+ <option key={p.id} value={p.id}>
696
+ {p.name}
697
+ </option>
698
+ ))}
699
+ </optgroup>
700
+ ))}
701
+ </select>
702
+ <a href={provider.docs} target="_blank" rel="noreferrer">
703
+ Provider docs
704
+ </a>
705
+ </div>
706
+ </div>
707
+ );
708
+ }
709
+
710
+ if (show === 'install') {
711
+ return part(
712
+ 'Install',
713
+ code(install, 'bash'),
714
+ <div className="provider-part-tabs" role="group" aria-label="Package manager">
715
+ {managers.map(([name]) => (
716
+ <button
717
+ key={name}
718
+ type="button"
719
+ aria-pressed={state.manager === name}
720
+ onClick={() => store.update({ manager: name })}
721
+ >
722
+ {name}
723
+ </button>
724
+ ))}
725
+ </div>,
726
+ );
727
+ }
728
+
729
+ if (show === 'env') {
730
+ return part(
731
+ 'Environment',
732
+ <>
733
+ {provider.env.length === 0 ? (
734
+ <p className="provider-part-text">No variables.</p>
735
+ ) : (
736
+ code(env, 'bash')
737
+ )}
738
+ {provider.readsAtLoad || provider.note ? (
739
+ <p className="provider-part-text provider-part-note">
740
+ {[
741
+ provider.readsAtLoad
742
+ ? 'This provider reads the variables when the config loads. If one is missing, all runs stop with CONFIG_LOAD_FAILED.'
743
+ : null,
744
+ provider.note,
745
+ ]
746
+ .filter(Boolean)
747
+ .join(' ')}
748
+ </p>
749
+ ) : null}
750
+ </>,
751
+ );
752
+ }
753
+
754
+ if (show === 'config') {
755
+ return part('e2e.config.ts', code(config, 'ts'));
756
+ }
757
+
758
+ if (show === 'model') {
759
+ return part('Model setup', code(model, 'ts'));
760
+ }
761
+
762
+ return null;
763
+ };