auth-options.types.ts 14 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276
  1. import { Config } from "effect"
  2. import { Auth } from "../src/route"
  3. import type { LanguageModelFactory } from "../src/route/auth-options"
  4. import * as OpenAIChat from "../src/protocols/openai-chat"
  5. import * as AmazonBedrock from "../src/providers/amazon-bedrock"
  6. import * as Anthropic from "../src/providers/anthropic"
  7. import * as AnthropicCompatible from "../src/providers/anthropic-compatible"
  8. import * as Azure from "../src/providers/azure"
  9. import * as Cloudflare from "../src/providers/cloudflare"
  10. import * as GitHubCopilot from "../src/providers/github-copilot"
  11. import * as Google from "../src/providers/google"
  12. import * as GoogleVertex from "../src/providers/google-vertex"
  13. import * as GoogleVertexChat from "../src/providers/google-vertex-chat"
  14. import * as GoogleVertexMessages from "../src/providers/google-vertex-messages"
  15. import * as GoogleVertexResponses from "../src/providers/google-vertex-responses"
  16. import * as OpenAI from "../src/providers/openai"
  17. import * as OpenAICompatible from "../src/providers/openai-compatible"
  18. import * as OpenRouter from "../src/providers/openrouter"
  19. import * as XAI from "../src/providers/xai"
  20. type BaseOptions = {
  21. readonly baseURL?: string
  22. readonly headers?: Record<string, string>
  23. }
  24. type LanguageModel = {
  25. readonly id: string
  26. }
  27. declare const auth: Auth.Definition
  28. declare const optionalAuthModel: LanguageModelFactory<BaseOptions, "optional", LanguageModel>
  29. declare const requiredAuthModel: LanguageModelFactory<BaseOptions, "required", LanguageModel>
  30. const configApiKey = Config.redacted("OPENAI_API_KEY")
  31. OpenAIChat.route.model({ id: "gpt-4.1-mini" })
  32. // @ts-expect-error route model selection does not configure endpoints.
  33. OpenAIChat.route.model({ id: "gpt-4.1-mini", baseURL: "https://gateway.example.com/v1" })
  34. // @ts-expect-error route model selection does not configure query params.
  35. OpenAIChat.route.model({ id: "gpt-4.1-mini", queryParams: { debug: "1" } })
  36. // @ts-expect-error route model selection does not configure auth.
  37. OpenAIChat.route.model({ id: "gpt-4.1-mini", auth })
  38. // @ts-expect-error route model selection does not configure api keys.
  39. OpenAIChat.route.model({ id: "gpt-4.1-mini", apiKey: "sk-test" })
  40. optionalAuthModel("gpt-4.1-mini")
  41. optionalAuthModel("gpt-4.1-mini", {})
  42. optionalAuthModel("gpt-4.1-mini", { apiKey: "sk-test" })
  43. optionalAuthModel("gpt-4.1-mini", { apiKey: configApiKey })
  44. optionalAuthModel("gpt-4.1-mini", { auth })
  45. optionalAuthModel("gpt-4.1-mini", { auth, baseURL: "https://gateway.example.com/v1" })
  46. optionalAuthModel("gpt-4.1-mini", { apiKey: "sk-test", headers: { "x-source": "test" } })
  47. // @ts-expect-error auth is an override, so apiKey cannot be supplied with it.
  48. optionalAuthModel("gpt-4.1-mini", { apiKey: "sk-test", auth })
  49. requiredAuthModel("custom-model", { apiKey: "key" })
  50. requiredAuthModel("custom-model", { apiKey: configApiKey })
  51. requiredAuthModel("custom-model", { auth })
  52. requiredAuthModel("custom-model", { auth, headers: { "x-tenant-id": "tenant" } })
  53. // @ts-expect-error providers without config fallback need apiKey or auth.
  54. requiredAuthModel("custom-model")
  55. // @ts-expect-error providers without config fallback need apiKey or auth.
  56. requiredAuthModel("custom-model", {})
  57. // @ts-expect-error auth is an override, so apiKey cannot be supplied with it.
  58. requiredAuthModel("custom-model", { apiKey: "key", auth })
  59. OpenAI.responses("gpt-4.1-mini")
  60. OpenAI.configure({}).responses("gpt-4.1-mini")
  61. OpenAI.configure({ apiKey: "sk-test" }).responses("gpt-4.1-mini")
  62. OpenAI.configure({ apiKey: configApiKey }).responses("gpt-4.1-mini")
  63. OpenAI.configure({ auth: Auth.bearer("oauth-token") }).responses("gpt-4.1-mini")
  64. OpenAI.configure({
  65. auth: Auth.headers({ authorization: "Bearer gateway" }),
  66. baseURL: "https://gateway.example.com/v1",
  67. }).responses("gpt-4.1-mini")
  68. OpenAI.configure({
  69. generation: { maxTokens: 100 },
  70. providerOptions: { openai: { store: false } },
  71. }).responses("gpt-4.1-mini")
  72. // @ts-expect-error OpenAI model selectors only accept model ids.
  73. OpenAI.configure({ apiKey: "sk-test" }).responses("gpt-4.1-mini", {})
  74. // @ts-expect-error apiKey only accepts string, Redacted<string>, or Config<string | Redacted<string>>.
  75. OpenAI.configure({ apiKey: 123 })
  76. // @ts-expect-error provider helpers reject unknown top-level options.
  77. OpenAI.configure({ bogus: true })
  78. // @ts-expect-error common generation options remain typed.
  79. OpenAI.configure({ generation: { maxTokens: "many" } })
  80. // @ts-expect-error provider-native options remain typed.
  81. OpenAI.configure({ providerOptions: { openai: { store: "false" } } })
  82. // @ts-expect-error auth is an override, so OpenAI rejects apiKey with auth.
  83. OpenAI.configure({ apiKey: "sk-test", auth: Auth.bearer("oauth-token") })
  84. OpenAI.chat("gpt-4.1-mini")
  85. OpenAI.configure({ apiKey: "sk-test" }).chat("gpt-4.1-mini")
  86. OpenAI.configure({ apiKey: configApiKey }).chat("gpt-4.1-mini")
  87. OpenAI.configure({ auth: Auth.bearer("oauth-token") }).chat("gpt-4.1-mini")
  88. // @ts-expect-error OpenAI chat selectors only accept model ids.
  89. OpenAI.configure({ apiKey: "sk-test" }).chat("gpt-4.1-mini", {})
  90. // @ts-expect-error auth is an override, so OpenAI Chat rejects apiKey with auth.
  91. OpenAI.configure({ apiKey: "sk-test", auth: Auth.bearer("oauth-token") })
  92. // @ts-expect-error Azure requires at least one of `resourceName` or `baseURL`.
  93. Azure.configure()
  94. Azure.configure({ apiKey: "azure-key", resourceName: "resource" }).responses("deployment")
  95. Azure.configure({ apiKey: configApiKey, resourceName: "resource" }).responses("deployment")
  96. Azure.configure({ auth: Auth.header("api-key", "azure-key"), resourceName: "resource" }).responses("deployment")
  97. // @ts-expect-error Azure model selectors only accept deployment ids.
  98. Azure.configure({ apiKey: "azure-key", resourceName: "resource" }).responses("deployment", {})
  99. // @ts-expect-error auth is an override, so Azure rejects apiKey with auth.
  100. Azure.configure({ resourceName: "resource", apiKey: "azure-key", auth: Auth.header("api-key", "override") })
  101. Azure.configure({ apiKey: "azure-key", resourceName: "resource" }).chat("deployment")
  102. Azure.configure({ apiKey: configApiKey, resourceName: "resource" }).chat("deployment")
  103. Azure.configure({ auth: Auth.header("api-key", "azure-key"), resourceName: "resource" }).chat("deployment")
  104. // @ts-expect-error Azure chat model selectors only accept deployment ids.
  105. Azure.configure({ apiKey: "azure-key", resourceName: "resource" }).chat("deployment", {})
  106. // @ts-expect-error auth is an override, so Azure Chat rejects apiKey with auth.
  107. Azure.configure({ resourceName: "resource", apiKey: "azure-key", auth: Auth.header("api-key", "override") })
  108. Anthropic.configure({ apiKey: "anthropic-key" }).model("claude-haiku")
  109. Anthropic.configure({
  110. apiKey: "anthropic-key",
  111. providerOptions: {
  112. anthropic: { thinking: { type: "enabled", budgetTokens: 1_024 }, effort: "high" },
  113. },
  114. }).model("claude-haiku")
  115. // @ts-expect-error Anthropic model selectors only accept model ids.
  116. Anthropic.configure({ apiKey: "anthropic-key" }).model("claude-haiku", {})
  117. // @ts-expect-error Anthropic package settings accept only one auth source.
  118. Anthropic.model("claude-sonnet-4-6", { apiKey: "anthropic-key", authToken: "anthropic-token" })
  119. // @ts-expect-error Enabled Anthropic thinking requires a token budget.
  120. Anthropic.configure({ providerOptions: { anthropic: { thinking: { type: "enabled" } } } })
  121. // @ts-expect-error Anthropic thinking budgets must be numbers.
  122. Anthropic.configure({ providerOptions: { anthropic: { thinking: { type: "enabled", budgetTokens: "large" } } } })
  123. AnthropicCompatible.configure({
  124. apiKey: "messages-key",
  125. baseURL: "https://messages.example.com/v1",
  126. provider: "example",
  127. providerOptions: { anthropic: { thinking: { type: "disabled" } } },
  128. }).model("compatible-model")
  129. // @ts-expect-error Anthropic-compatible providers require a base URL.
  130. AnthropicCompatible.configure({ apiKey: "messages-key" })
  131. // @ts-expect-error Anthropic-compatible model selectors only accept model ids.
  132. AnthropicCompatible.configure({ baseURL: "https://messages.example.com/v1" }).model("compatible-model", {})
  133. // @ts-expect-error Anthropic-compatible package settings accept only one auth source.
  134. AnthropicCompatible.model("compatible-model", {
  135. apiKey: "messages-key",
  136. authToken: "messages-token",
  137. baseURL: "https://messages.example.com/v1",
  138. })
  139. Google.configure({ apiKey: "google-key" }).model("gemini-2.5-flash")
  140. Google.configure({
  141. apiKey: "google-key",
  142. providerOptions: { gemini: { thinkingConfig: { thinkingBudget: 0, includeThoughts: false } } },
  143. }).model("gemini-2.5-flash")
  144. // @ts-expect-error Google model selectors only accept model ids.
  145. Google.configure({ apiKey: "google-key" }).model("gemini-2.5-flash", {})
  146. // @ts-expect-error Gemini thinking budgets must be numbers.
  147. Google.configure({ providerOptions: { gemini: { thinkingConfig: { thinkingBudget: "large" } } } })
  148. GoogleVertex.configure({
  149. apiKey: "vertex-key",
  150. providerOptions: { gemini: { thinkingConfig: { thinkingBudget: 1_024 } } },
  151. }).model("gemini-3.5-flash")
  152. GoogleVertex.configure({ accessToken: "vertex-token", project: "project" }).model("gemini-3.5-flash")
  153. GoogleVertex.configure({ auth: Auth.bearer("vertex-token"), project: "project" }).model("gemini-3.5-flash")
  154. // @ts-expect-error Vertex Gemini model selectors only accept model ids.
  155. GoogleVertex.configure({ apiKey: "vertex-key" }).model("gemini-3.5-flash", {})
  156. // @ts-expect-error Vertex Gemini config accepts only one auth source.
  157. GoogleVertex.configure({ accessToken: "vertex-token", apiKey: "vertex-key", project: "project" })
  158. // @ts-expect-error Vertex Gemini package settings accept only one auth source.
  159. GoogleVertex.model("gemini-3.5-flash", { accessToken: "vertex-token", apiKey: "vertex-key", project: "project" })
  160. GoogleVertexChat.configure({ accessToken: "vertex-token", project: "project" }).model("deepseek-ai/deepseek-v3.2-maas")
  161. GoogleVertexChat.configure({ auth: Auth.bearer("vertex-token"), project: "project" }).model(
  162. "deepseek-ai/deepseek-v3.2-maas",
  163. )
  164. // @ts-expect-error Vertex Chat package settings do not accept API keys.
  165. GoogleVertexChat.model("deepseek-ai/deepseek-v3.2-maas", { apiKey: "vertex-key", project: "project" })
  166. GoogleVertexChat.configure({ accessToken: "vertex-token", project: "project" }).model(
  167. "deepseek-ai/deepseek-v3.2-maas",
  168. // @ts-expect-error Vertex Chat model selectors only accept model ids.
  169. {},
  170. )
  171. GoogleVertexChat.configure({
  172. accessToken: "vertex-token",
  173. // @ts-expect-error Vertex Chat config accepts only one auth source.
  174. auth: Auth.bearer("vertex-token"),
  175. project: "project",
  176. })
  177. GoogleVertexResponses.configure({ accessToken: "vertex-token", project: "project" }).model("xai/grok-4.20-reasoning")
  178. GoogleVertexResponses.configure({ auth: Auth.bearer("vertex-token"), project: "project" }).model(
  179. "xai/grok-4.20-reasoning",
  180. )
  181. // @ts-expect-error Vertex Responses package settings do not accept API keys.
  182. GoogleVertexResponses.model("xai/grok-4.20-reasoning", { apiKey: "vertex-key", project: "project" })
  183. GoogleVertexResponses.configure({ accessToken: "vertex-token", project: "project" }).model(
  184. "xai/grok-4.20-reasoning",
  185. // @ts-expect-error Vertex Responses model selectors only accept model ids.
  186. {},
  187. )
  188. GoogleVertexResponses.configure({
  189. accessToken: "vertex-token",
  190. // @ts-expect-error Vertex Responses config accepts only one auth source.
  191. auth: Auth.bearer("vertex-token"),
  192. project: "project",
  193. })
  194. GoogleVertexMessages.configure({
  195. accessToken: "vertex-token",
  196. project: "project",
  197. providerOptions: { anthropic: { thinking: { type: "adaptive", display: "omitted" }, effort: "low" } },
  198. }).model("claude-sonnet-4-6")
  199. // @ts-expect-error Vertex Messages package settings do not accept API keys.
  200. GoogleVertexMessages.model("claude-sonnet-4-6", { apiKey: "vertex-key", project: "project" })
  201. GoogleVertexMessages.configure({ auth: Auth.bearer("vertex-token"), project: "project" }).model("claude-sonnet-4-6")
  202. GoogleVertexMessages.configure({ accessToken: "vertex-token", project: "project" }).model(
  203. "claude-sonnet-4-6",
  204. // @ts-expect-error Vertex Messages model selectors only accept model ids.
  205. {},
  206. )
  207. GoogleVertexMessages.configure({
  208. accessToken: "vertex-token",
  209. // @ts-expect-error Vertex Messages config accepts only one auth source.
  210. auth: Auth.bearer("vertex-token"),
  211. project: "project",
  212. })
  213. AmazonBedrock.configure({ apiKey: "bedrock-key" }).model("anthropic.claude")
  214. // @ts-expect-error Bedrock model selectors only accept model ids.
  215. AmazonBedrock.configure({ apiKey: "bedrock-key" }).model("anthropic.claude", {})
  216. OpenRouter.configure({ apiKey: "openrouter-key" }).model("openai/gpt-4o-mini")
  217. // @ts-expect-error OpenRouter model selectors only accept model ids.
  218. OpenRouter.configure({ apiKey: "openrouter-key" }).model("openai/gpt-4o-mini", {})
  219. XAI.configure({ apiKey: "xai-key" }).responses("grok-4")
  220. XAI.configure({ apiKey: "xai-key" }).chat("grok-4")
  221. // @ts-expect-error xAI Responses selectors only accept model ids.
  222. XAI.configure({ apiKey: "xai-key" }).responses("grok-4", {})
  223. // @ts-expect-error xAI Chat selectors only accept model ids.
  224. XAI.configure({ apiKey: "xai-key" }).chat("grok-4", {})
  225. OpenAICompatible.deepseek.configure({ apiKey: "deepseek-key" }).model("deepseek-chat")
  226. // @ts-expect-error OpenAI-compatible family selectors only accept model ids.
  227. OpenAICompatible.deepseek.configure({ apiKey: "deepseek-key" }).model("deepseek-chat", {})
  228. Cloudflare.CloudflareWorkersAI.configure({ accountId: "account", apiKey: "cf-key" }).model("@cf/meta/llama")
  229. // @ts-expect-error Cloudflare Workers AI model selectors only accept model ids.
  230. Cloudflare.CloudflareWorkersAI.configure({ accountId: "account", apiKey: "cf-key" }).model("@cf/meta/llama", {})
  231. GitHubCopilot.configure({ baseURL: "https://copilot.test", apiKey: "copilot-key" }).model("gpt-4.1")
  232. // @ts-expect-error GitHub Copilot model selectors only accept model ids.
  233. GitHubCopilot.configure({ baseURL: "https://copilot.test", apiKey: "copilot-key" }).model("gpt-4.1", {})