copilot-provider.ts 3.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100
  1. import type { LanguageModelV3 } from "@ai-sdk/provider"
  2. import { type FetchFunction, withoutTrailingSlash, withUserAgentSuffix } from "@ai-sdk/provider-utils"
  3. import { OpenAICompatibleChatLanguageModel } from "./chat/openai-compatible-chat-language-model"
  4. import { OpenAIResponsesLanguageModel } from "./responses/openai-responses-language-model"
  5. // Import the version or define it
  6. const VERSION = "0.1.0"
  7. export type OpenaiCompatibleModelId = string
  8. export interface OpenaiCompatibleProviderSettings {
  9. /**
  10. * API key for authenticating requests.
  11. */
  12. apiKey?: string
  13. /**
  14. * Base URL for the OpenAI Compatible API calls.
  15. */
  16. baseURL?: string
  17. /**
  18. * Name of the provider.
  19. */
  20. name?: string
  21. /**
  22. * Custom headers to include in the requests.
  23. */
  24. headers?: Record<string, string>
  25. /**
  26. * Custom fetch implementation.
  27. */
  28. fetch?: FetchFunction
  29. }
  30. export interface OpenaiCompatibleProvider {
  31. (modelId: OpenaiCompatibleModelId): LanguageModelV3
  32. chat(modelId: OpenaiCompatibleModelId): LanguageModelV3
  33. responses(modelId: OpenaiCompatibleModelId): LanguageModelV3
  34. languageModel(modelId: OpenaiCompatibleModelId): LanguageModelV3
  35. // embeddingModel(modelId: any): EmbeddingModelV2
  36. // imageModel(modelId: any): ImageModelV2
  37. }
  38. /**
  39. * Create an OpenAI Compatible provider instance.
  40. */
  41. export function createOpenaiCompatible(options: OpenaiCompatibleProviderSettings = {}): OpenaiCompatibleProvider {
  42. const baseURL = withoutTrailingSlash(options.baseURL ?? "https://api.openai.com/v1")
  43. if (!baseURL) {
  44. throw new Error("baseURL is required")
  45. }
  46. // Merge headers: defaults first, then user overrides
  47. const headers = {
  48. // Default OpenAI Compatible headers (can be overridden by user)
  49. ...(options.apiKey && { Authorization: `Bearer ${options.apiKey}` }),
  50. ...options.headers,
  51. }
  52. const getHeaders = () => withUserAgentSuffix(headers, `ai-sdk/openai-compatible/${VERSION}`)
  53. const createChatModel = (modelId: OpenaiCompatibleModelId) => {
  54. return new OpenAICompatibleChatLanguageModel(modelId, {
  55. provider: `${options.name ?? "openai-compatible"}.chat`,
  56. headers: getHeaders,
  57. url: ({ path }) => `${baseURL}${path}`,
  58. fetch: options.fetch,
  59. })
  60. }
  61. const createResponsesModel = (modelId: OpenaiCompatibleModelId) => {
  62. return new OpenAIResponsesLanguageModel(modelId, {
  63. provider: `${options.name ?? "openai-compatible"}.responses`,
  64. headers: getHeaders,
  65. url: ({ path }) => `${baseURL}${path}`,
  66. fetch: options.fetch,
  67. })
  68. }
  69. const createLanguageModel = (modelId: OpenaiCompatibleModelId) => createChatModel(modelId)
  70. const provider = function (modelId: OpenaiCompatibleModelId) {
  71. return createChatModel(modelId)
  72. }
  73. provider.languageModel = createLanguageModel
  74. provider.chat = createChatModel
  75. provider.responses = createResponsesModel
  76. return provider as OpenaiCompatibleProvider
  77. }
  78. // Default OpenAI Compatible provider instance
  79. export const openaiCompatible = createOpenaiCompatible()