golden.recorded.test.ts 7.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223
  1. import * as Anthropic from "../../src/providers/anthropic"
  2. import { CloudflareAIGateway, CloudflareWorkersAI } from "../../src/providers/cloudflare"
  3. import * as Google from "../../src/providers/google"
  4. import * as OpenAI from "../../src/providers/openai"
  5. import * as OpenAICompatible from "../../src/providers/openai-compatible"
  6. import * as OpenRouter from "../../src/providers/openrouter"
  7. import * as XAI from "../../src/providers/xai"
  8. import { describeRecordedGoldenScenarios } from "../recorded-golden"
  9. const openAI = OpenAI.configure({
  10. apiKey: process.env.OPENAI_API_KEY ?? "fixture",
  11. })
  12. const openAIChat = openAI.chat("gpt-4o-mini")
  13. const openAIResponses = openAI.responses("gpt-5.5")
  14. const openAIResponsesWebSocket = openAI.responsesWebSocket("gpt-4.1-mini")
  15. const anthropic = Anthropic.configure({
  16. apiKey: process.env.ANTHROPIC_API_KEY ?? "fixture",
  17. })
  18. const anthropicHaiku = anthropic.model("claude-haiku-4-5-20251001")
  19. const anthropicOpus = anthropic.model("claude-opus-4-7")
  20. const google = Google.configure({ apiKey: process.env.GOOGLE_GENERATIVE_AI_API_KEY ?? "fixture" })
  21. const gemini = google.model("gemini-2.5-flash")
  22. const xai = XAI.configure({ apiKey: process.env.XAI_API_KEY ?? "fixture" })
  23. const xaiBasic = xai.model("grok-3-mini")
  24. const xaiFlagship = xai.model("grok-4.3")
  25. const cloudflareAIGateway = CloudflareAIGateway.configure({
  26. accountId: process.env.CLOUDFLARE_ACCOUNT_ID ?? "fixture-account",
  27. gatewayId:
  28. process.env.CLOUDFLARE_GATEWAY_ID && process.env.CLOUDFLARE_GATEWAY_ID !== process.env.CLOUDFLARE_ACCOUNT_ID
  29. ? process.env.CLOUDFLARE_GATEWAY_ID
  30. : undefined,
  31. gatewayApiKey: process.env.CLOUDFLARE_API_TOKEN ?? "fixture",
  32. })
  33. const cloudflareWorkers = CloudflareWorkersAI.configure({
  34. accountId: process.env.CLOUDFLARE_ACCOUNT_ID ?? "fixture-account",
  35. apiKey: process.env.CLOUDFLARE_API_KEY ?? "fixture",
  36. })
  37. const cloudflareAIGatewayWorkers = cloudflareAIGateway.model("workers-ai/@cf/meta/llama-3.1-8b-instruct")
  38. const cloudflareAIGatewayWorkersTools = cloudflareAIGateway.model("workers-ai/@cf/openai/gpt-oss-20b")
  39. const cloudflareWorkersAI = cloudflareWorkers.model("@cf/meta/llama-3.1-8b-instruct")
  40. const cloudflareWorkersAITools = cloudflareWorkers.model("@cf/openai/gpt-oss-20b")
  41. const deepseek = OpenAICompatible.deepseek
  42. .configure({ apiKey: process.env.DEEPSEEK_API_KEY ?? "fixture" })
  43. .model("deepseek-chat")
  44. const together = OpenAICompatible.togetherai
  45. .configure({
  46. apiKey: process.env.TOGETHER_AI_API_KEY ?? "fixture",
  47. })
  48. .model("meta-llama/Llama-3.3-70B-Instruct-Turbo")
  49. const groq = OpenAICompatible.groq
  50. .configure({ apiKey: process.env.GROQ_API_KEY ?? "fixture" })
  51. .model("llama-3.3-70b-versatile")
  52. const openRouter = OpenRouter.configure({ apiKey: process.env.OPENROUTER_API_KEY ?? "fixture" })
  53. const openrouter = openRouter.model("openai/gpt-4o-mini")
  54. const openrouterGpt55 = openRouter.model("openai/gpt-5.5")
  55. const openrouterOpus = OpenRouter.configure({
  56. apiKey: process.env.OPENROUTER_API_KEY ?? "fixture",
  57. }).model("anthropic/claude-opus-4.7")
  58. const redactCloudflareURL = (url: string) =>
  59. url
  60. .replace(/\/client\/v4\/accounts\/[^/]+\/ai\/v1\//, "/client/v4/accounts/{account}/ai/v1/")
  61. .replace(/\/v1\/[^/]+\/[^/]+\/compat\//, "/v1/{account}/{gateway}/compat/")
  62. const cloudflareOptions = {
  63. redact: { url: redactCloudflareURL },
  64. }
  65. describeRecordedGoldenScenarios([
  66. {
  67. name: "OpenAI Chat gpt-4o-mini",
  68. prefix: "openai-chat",
  69. model: openAIChat,
  70. requires: ["OPENAI_API_KEY"],
  71. scenarios: ["text", "tool-call", "tool-loop", { id: "image-tool-result", maxTokens: 40 }],
  72. },
  73. {
  74. name: "OpenAI Responses gpt-5.5",
  75. prefix: "openai-responses",
  76. model: openAIResponses,
  77. requires: ["OPENAI_API_KEY"],
  78. tags: ["flagship"],
  79. scenarios: [
  80. { id: "text", temperature: false },
  81. { id: "reasoning", temperature: false },
  82. { id: "reasoning-continuation", temperature: false },
  83. { id: "tool-call", temperature: false },
  84. { id: "tool-loop", temperature: false },
  85. { id: "image-tool-result", temperature: false, maxTokens: 40 },
  86. ],
  87. },
  88. {
  89. name: "OpenAI Responses WebSocket gpt-4.1-mini",
  90. prefix: "openai-responses-websocket",
  91. model: openAIResponsesWebSocket,
  92. transport: "websocket",
  93. requires: ["OPENAI_API_KEY"],
  94. scenarios: ["tool-loop"],
  95. },
  96. {
  97. name: "Anthropic Haiku 4.5",
  98. prefix: "anthropic-messages",
  99. model: anthropicHaiku,
  100. requires: ["ANTHROPIC_API_KEY"],
  101. options: { redact: { allowRequestHeaders: ["anthropic-version"] } },
  102. scenarios: ["text", "tool-call"],
  103. },
  104. {
  105. name: "Anthropic Opus 4.7",
  106. prefix: "anthropic-messages",
  107. model: anthropicOpus,
  108. requires: ["ANTHROPIC_API_KEY"],
  109. tags: ["flagship"],
  110. options: { redact: { allowRequestHeaders: ["anthropic-version"] } },
  111. scenarios: [
  112. { id: "tool-loop", temperature: false },
  113. { id: "image-tool-result", temperature: false, maxTokens: 40 },
  114. ],
  115. },
  116. {
  117. name: "Gemini 2.5 Flash",
  118. prefix: "gemini",
  119. model: gemini,
  120. requires: ["GOOGLE_GENERATIVE_AI_API_KEY"],
  121. scenarios: [
  122. { id: "text", maxTokens: 80 },
  123. "tool-call",
  124. { id: "image", maxTokens: 160 },
  125. { id: "image-tool-result", maxTokens: 40 },
  126. ],
  127. },
  128. {
  129. name: "xAI Grok 3 Mini",
  130. prefix: "xai",
  131. model: xaiBasic,
  132. requires: ["XAI_API_KEY"],
  133. scenarios: ["text", "tool-call"],
  134. },
  135. {
  136. name: "xAI Grok 4.3",
  137. prefix: "xai",
  138. model: xaiFlagship,
  139. requires: ["XAI_API_KEY"],
  140. tags: ["flagship"],
  141. scenarios: [{ id: "tool-loop", timeout: 30_000 }],
  142. },
  143. {
  144. name: "Cloudflare AI Gateway Workers AI Llama 3.1 8B",
  145. prefix: "cloudflare-ai-gateway",
  146. model: cloudflareAIGatewayWorkers,
  147. requires: ["CLOUDFLARE_ACCOUNT_ID", "CLOUDFLARE_API_TOKEN"],
  148. options: cloudflareOptions,
  149. scenarios: ["text"],
  150. },
  151. {
  152. name: "Cloudflare AI Gateway Workers AI GPT OSS 20B Tools",
  153. prefix: "cloudflare-ai-gateway",
  154. model: cloudflareAIGatewayWorkersTools,
  155. requires: ["CLOUDFLARE_ACCOUNT_ID", "CLOUDFLARE_API_TOKEN"],
  156. options: cloudflareOptions,
  157. scenarios: [{ id: "tool-call", maxTokens: 120 }],
  158. },
  159. {
  160. name: "Cloudflare Workers AI Llama 3.1 8B",
  161. prefix: "cloudflare-workers-ai",
  162. model: cloudflareWorkersAI,
  163. requires: ["CLOUDFLARE_ACCOUNT_ID", "CLOUDFLARE_API_KEY"],
  164. options: cloudflareOptions,
  165. scenarios: ["text"],
  166. },
  167. {
  168. name: "Cloudflare Workers AI GPT OSS 20B Tools",
  169. prefix: "cloudflare-workers-ai",
  170. model: cloudflareWorkersAITools,
  171. requires: ["CLOUDFLARE_ACCOUNT_ID", "CLOUDFLARE_API_KEY"],
  172. options: cloudflareOptions,
  173. scenarios: [{ id: "tool-call", maxTokens: 120 }],
  174. },
  175. {
  176. name: "DeepSeek Chat",
  177. prefix: "openai-compatible-chat",
  178. model: deepseek,
  179. requires: ["DEEPSEEK_API_KEY"],
  180. scenarios: ["text"],
  181. },
  182. {
  183. name: "TogetherAI Llama 3.3 70B",
  184. prefix: "openai-compatible-chat",
  185. model: together,
  186. requires: ["TOGETHER_AI_API_KEY"],
  187. scenarios: ["text", "tool-call"],
  188. },
  189. {
  190. name: "Groq Llama 3.3 70B",
  191. prefix: "openai-compatible-chat",
  192. model: groq,
  193. requires: ["GROQ_API_KEY"],
  194. scenarios: ["text", "tool-call", { id: "tool-loop", timeout: 30_000 }],
  195. },
  196. {
  197. name: "OpenRouter gpt-4o-mini",
  198. prefix: "openai-compatible-chat",
  199. model: openrouter,
  200. requires: ["OPENROUTER_API_KEY"],
  201. scenarios: ["text", "tool-call", "tool-loop"],
  202. },
  203. {
  204. name: "OpenRouter gpt-5.5",
  205. prefix: "openai-compatible-chat",
  206. model: openrouterGpt55,
  207. requires: ["OPENROUTER_API_KEY"],
  208. tags: ["flagship"],
  209. scenarios: ["tool-loop"],
  210. },
  211. {
  212. name: "OpenRouter Claude Opus 4.7",
  213. prefix: "openai-compatible-chat",
  214. model: openrouterOpus,
  215. requires: ["OPENROUTER_API_KEY"],
  216. tags: ["flagship"],
  217. scenarios: ["tool-loop"],
  218. },
  219. ])