provider-azure-cognitive-services.test.ts 5.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141
  1. import { describe, expect } from "bun:test"
  2. import { Effect } from "effect"
  3. import { Catalog } from "@opencode-ai/core/catalog"
  4. import { PluginV2 } from "@opencode-ai/core/plugin"
  5. import { AzureCognitiveServicesPlugin } from "@opencode-ai/core/plugin/provider/azure"
  6. import { ProviderV2 } from "@opencode-ai/core/provider"
  7. import { fakeSelectorSdk, it, model, provider, withEnv } from "./provider-helper"
  8. describe("AzureCognitiveServicesPlugin", () => {
  9. it.effect("maps the resource env var to the Azure SDK baseURL", () =>
  10. withEnv({ AZURE_COGNITIVE_SERVICES_RESOURCE_NAME: "cognitive" }, () =>
  11. Effect.gen(function* () {
  12. const plugin = yield* PluginV2.Service
  13. const catalog = yield* Catalog.Service
  14. yield* plugin.add(AzureCognitiveServicesPlugin)
  15. const transform = yield* catalog.transform()
  16. yield* transform((catalog) => {
  17. catalog.provider.update(ProviderV2.ID.make("azure-cognitive-services"), (item) => {
  18. item.api = { type: "aisdk", package: "@ai-sdk/openai-compatible" }
  19. })
  20. })
  21. const result = yield* catalog.provider.get(ProviderV2.ID.make("azure-cognitive-services"))
  22. expect(result.api).toEqual({
  23. type: "aisdk",
  24. package: "@ai-sdk/openai-compatible",
  25. url: "https://cognitive.cognitiveservices.azure.com/openai",
  26. })
  27. expect(result.request.body.baseURL).toBeUndefined()
  28. expect(result.request.body.resourceName).toBeUndefined()
  29. }),
  30. ),
  31. )
  32. it.effect("leaves baseURL unset without resource env and ignores other providers", () =>
  33. withEnv({ AZURE_COGNITIVE_SERVICES_RESOURCE_NAME: undefined }, () =>
  34. Effect.gen(function* () {
  35. const plugin = yield* PluginV2.Service
  36. const catalog = yield* Catalog.Service
  37. yield* plugin.add(AzureCognitiveServicesPlugin)
  38. const transform = yield* catalog.transform()
  39. yield* transform((catalog) => {
  40. const azure = provider("azure-cognitive-services", {
  41. api: { type: "aisdk", package: "@ai-sdk/openai-compatible" },
  42. })
  43. const openai = provider("openai")
  44. catalog.provider.update(azure.id, (item) => {
  45. item.api = azure.api
  46. })
  47. catalog.provider.update(openai.id, (item) => {
  48. item.api = openai.api
  49. })
  50. })
  51. const azure = yield* catalog.provider.get(ProviderV2.ID.make("azure-cognitive-services"))
  52. const openai = yield* catalog.provider.get(ProviderV2.ID.openai)
  53. expect(azure.request.body.baseURL).toBeUndefined()
  54. expect(azure.api).toEqual({ type: "aisdk", package: "@ai-sdk/openai-compatible" })
  55. expect(openai.request.body.baseURL).toBeUndefined()
  56. expect(openai.api).toEqual({ type: "aisdk", package: "test-provider" })
  57. }),
  58. ),
  59. )
  60. it.effect("selects chat only for completion URLs", () =>
  61. Effect.gen(function* () {
  62. const plugin = yield* PluginV2.Service
  63. const calls: string[] = []
  64. yield* plugin.add(AzureCognitiveServicesPlugin)
  65. yield* plugin.trigger(
  66. "aisdk.language",
  67. {
  68. model: model("azure-cognitive-services", "deployment"),
  69. sdk: fakeSelectorSdk(calls),
  70. options: { useCompletionUrls: true },
  71. },
  72. {},
  73. )
  74. expect(calls).toEqual(["chat:deployment"])
  75. }),
  76. )
  77. it.effect("uses the legacy Azure selector order and provider guard", () =>
  78. Effect.gen(function* () {
  79. const plugin = yield* PluginV2.Service
  80. const calls: string[] = []
  81. yield* plugin.add(AzureCognitiveServicesPlugin)
  82. yield* plugin.trigger(
  83. "aisdk.language",
  84. { model: model("azure-cognitive-services", "deployment"), sdk: fakeSelectorSdk(calls), options: {} },
  85. {},
  86. )
  87. const ignored = yield* plugin.trigger(
  88. "aisdk.language",
  89. { model: model("openai", "deployment"), sdk: fakeSelectorSdk(calls), options: {} },
  90. {},
  91. )
  92. expect(calls).toEqual(["responses:deployment"])
  93. expect(ignored.language).toBeUndefined()
  94. }),
  95. )
  96. it.effect("falls back from responses to messages, chat, then languageModel", () =>
  97. Effect.gen(function* () {
  98. const plugin = yield* PluginV2.Service
  99. const calls: string[] = []
  100. const sdk = fakeSelectorSdk(calls)
  101. yield* plugin.add(AzureCognitiveServicesPlugin)
  102. yield* plugin.trigger(
  103. "aisdk.language",
  104. {
  105. model: model("azure-cognitive-services", "messages-deployment"),
  106. sdk: { messages: sdk.messages, chat: sdk.chat, languageModel: sdk.languageModel },
  107. options: {},
  108. },
  109. {},
  110. )
  111. yield* plugin.trigger(
  112. "aisdk.language",
  113. {
  114. model: model("azure-cognitive-services", "chat-deployment"),
  115. sdk: { chat: sdk.chat, languageModel: sdk.languageModel },
  116. options: {},
  117. },
  118. {},
  119. )
  120. yield* plugin.trigger(
  121. "aisdk.language",
  122. {
  123. model: model("azure-cognitive-services", "language-deployment"),
  124. sdk: { languageModel: sdk.languageModel },
  125. options: {},
  126. },
  127. {},
  128. )
  129. expect(calls).toEqual([
  130. "messages:messages-deployment",
  131. "chat:chat-deployment",
  132. "languageModel:language-deployment",
  133. ])
  134. }),
  135. )
  136. })