provider-xai.test.ts 3.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115
  1. import { describe, expect } from "bun:test"
  2. import { Effect } from "effect"
  3. import { ModelV2 } from "@opencode-ai/core/model"
  4. import { PluginV2 } from "@opencode-ai/core/plugin"
  5. import { XAIPlugin } from "@opencode-ai/core/plugin/provider/xai"
  6. import { ProviderV2 } from "@opencode-ai/core/provider"
  7. import { testEffect } from "../lib/effect"
  8. import { fakeSelectorSdk } from "./provider-helper"
  9. const it = testEffect(PluginV2.defaultLayer)
  10. const model = new ModelV2.Info({
  11. ...ModelV2.Info.empty(ProviderV2.ID.make("xai"), ModelV2.ID.make("grok-4")),
  12. apiID: ModelV2.ID.make("grok-4"),
  13. endpoint: {
  14. type: "aisdk",
  15. package: "@ai-sdk/xai",
  16. },
  17. })
  18. describe("XAIPlugin", () => {
  19. it.effect("creates an xAI SDK only for @ai-sdk/xai", () =>
  20. Effect.gen(function* () {
  21. const plugin = yield* PluginV2.Service
  22. yield* plugin.add(XAIPlugin)
  23. const ignored = yield* plugin.trigger(
  24. "aisdk.sdk",
  25. { model, package: "@ai-sdk/openai-compatible", options: {} },
  26. {},
  27. )
  28. const result = yield* plugin.trigger("aisdk.sdk", { model, package: "@ai-sdk/xai", options: {} }, {})
  29. expect(ignored.sdk).toBeUndefined()
  30. expect(typeof result.sdk?.responses).toBe("function")
  31. }),
  32. )
  33. it.effect("creates xAI SDKs for custom provider IDs", () =>
  34. Effect.gen(function* () {
  35. const plugin = yield* PluginV2.Service
  36. const providers: string[] = []
  37. yield* plugin.add(XAIPlugin)
  38. yield* plugin.add(
  39. PluginV2.define({
  40. id: PluginV2.ID.make("xai-sdk-name-observer"),
  41. effect: Effect.gen(function* () {
  42. return {
  43. "aisdk.sdk": Effect.fn(function* (evt) {
  44. if (!evt.sdk) return
  45. providers.push(evt.sdk.responses("grok-4").provider)
  46. }),
  47. }
  48. }),
  49. }),
  50. )
  51. yield* plugin.trigger(
  52. "aisdk.sdk",
  53. {
  54. model: new ModelV2.Info({ ...model, providerID: ProviderV2.ID.make("custom-xai") }),
  55. package: "@ai-sdk/xai",
  56. options: {},
  57. },
  58. {},
  59. )
  60. expect(providers).toEqual(["xai.responses"])
  61. }),
  62. )
  63. it.effect("uses responses with the model apiID for xAI language models", () =>
  64. Effect.gen(function* () {
  65. const plugin = yield* PluginV2.Service
  66. const calls: string[] = []
  67. yield* plugin.add(XAIPlugin)
  68. const result = yield* plugin.trigger(
  69. "aisdk.language",
  70. {
  71. model: new ModelV2.Info({ ...model, id: ModelV2.ID.make("alias"), apiID: ModelV2.ID.make("grok-4") }),
  72. sdk: fakeSelectorSdk(calls),
  73. options: {},
  74. },
  75. {},
  76. )
  77. expect(calls).toEqual(["responses:grok-4"])
  78. expect(result.language).toBeDefined()
  79. }),
  80. )
  81. it.effect("ignores non-xAI providers", () =>
  82. Effect.gen(function* () {
  83. const plugin = yield* PluginV2.Service
  84. const calls: string[] = []
  85. yield* plugin.add(XAIPlugin)
  86. const result = yield* plugin.trigger(
  87. "aisdk.language",
  88. {
  89. model: new ModelV2.Info({ ...model, providerID: ProviderV2.ID.openai }),
  90. sdk: fakeSelectorSdk(calls),
  91. options: {},
  92. },
  93. {},
  94. )
  95. expect(calls).toEqual([])
  96. expect(result.language).toBeUndefined()
  97. }),
  98. )
  99. })