provider-venice.test.ts 4.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129
  1. import { describe, expect } from "bun:test"
  2. import type { LanguageModelV3 } from "@ai-sdk/provider"
  3. import { Effect } from "effect"
  4. import { ModelV2 } from "@opencode-ai/core/model"
  5. import { PluginV2 } from "@opencode-ai/core/plugin"
  6. import { PluginHost } from "@opencode-ai/core/plugin/host"
  7. import { VenicePlugin } from "@opencode-ai/core/plugin/provider/venice"
  8. import { ProviderV2 } from "@opencode-ai/core/provider"
  9. import { testEffect } from "../lib/effect"
  10. import { PluginTestLayer } from "./fixture"
  11. const it = testEffect(PluginTestLayer)
  12. const addPlugin = Effect.fn(function* () {
  13. const plugin = yield* PluginV2.Service
  14. const host = yield* PluginHost.make()
  15. yield* plugin.add({ id: VenicePlugin.id, effect: VenicePlugin.effect(host) })
  16. })
  17. function fakeSelectorSdk(calls: string[]) {
  18. const make = (method: string) => (id: string) => {
  19. calls.push(`${method}:${id}`)
  20. return { modelId: id, provider: method, specificationVersion: "v3" } as unknown as LanguageModelV3
  21. }
  22. return {
  23. responses: make("responses"),
  24. messages: make("messages"),
  25. chat: make("chat"),
  26. languageModel: make("languageModel"),
  27. }
  28. }
  29. describe("VenicePlugin", () => {
  30. it.effect("creates a Venice SDK for venice-ai-sdk-provider", () =>
  31. Effect.gen(function* () {
  32. const plugin = yield* PluginV2.Service
  33. yield* addPlugin()
  34. const result = yield* plugin.trigger(
  35. "aisdk.sdk",
  36. {
  37. model: new ModelV2.Info({
  38. ...ModelV2.Info.empty(ProviderV2.ID.make("venice"), ModelV2.ID.make("model")),
  39. api: { id: ModelV2.ID.make("model"), type: "aisdk", package: "test-provider" },
  40. }),
  41. package: "venice-ai-sdk-provider",
  42. options: { name: "venice" },
  43. },
  44. {},
  45. )
  46. expect(result.sdk).toBeDefined()
  47. }),
  48. )
  49. it.effect("uses the model provider ID as the bundled Venice SDK name", () =>
  50. Effect.gen(function* () {
  51. const plugin = yield* PluginV2.Service
  52. yield* addPlugin()
  53. const result = yield* plugin.trigger(
  54. "aisdk.sdk",
  55. {
  56. model: new ModelV2.Info({
  57. ...ModelV2.Info.empty(ProviderV2.ID.make("custom-venice"), ModelV2.ID.make("model")),
  58. api: { id: ModelV2.ID.make("model"), type: "aisdk", package: "test-provider" },
  59. }),
  60. package: "venice-ai-sdk-provider",
  61. options: { name: "custom-venice", apiKey: "test" },
  62. },
  63. {},
  64. )
  65. expect(result.sdk).toBeDefined()
  66. expect(result.sdk.languageModel("model").provider).toBe("custom-venice.chat")
  67. }),
  68. )
  69. it.effect("only handles the bundled venice-ai-sdk-provider package", () =>
  70. Effect.gen(function* () {
  71. const plugin = yield* PluginV2.Service
  72. yield* addPlugin()
  73. const similar = yield* plugin.trigger(
  74. "aisdk.sdk",
  75. {
  76. model: new ModelV2.Info({
  77. ...ModelV2.Info.empty(ProviderV2.ID.make("venice"), ModelV2.ID.make("model")),
  78. api: { id: ModelV2.ID.make("model"), type: "aisdk", package: "test-provider" },
  79. }),
  80. package: "file:///tmp/venice-ai-sdk-provider.js",
  81. options: { name: "venice" },
  82. },
  83. {},
  84. )
  85. const other = yield* plugin.trigger(
  86. "aisdk.sdk",
  87. {
  88. model: new ModelV2.Info({
  89. ...ModelV2.Info.empty(ProviderV2.ID.make("venice"), ModelV2.ID.make("model")),
  90. api: { id: ModelV2.ID.make("model"), type: "aisdk", package: "test-provider" },
  91. }),
  92. package: "@ai-sdk/openai-compatible",
  93. options: { name: "venice" },
  94. },
  95. {},
  96. )
  97. expect(similar.sdk).toBeUndefined()
  98. expect(other.sdk).toBeUndefined()
  99. }),
  100. )
  101. it.effect("leaves Venice language selection to the default languageModel fallback", () =>
  102. Effect.gen(function* () {
  103. const plugin = yield* PluginV2.Service
  104. const calls: string[] = []
  105. yield* addPlugin()
  106. const result = yield* plugin.trigger(
  107. "aisdk.language",
  108. {
  109. model: new ModelV2.Info({
  110. ...ModelV2.Info.empty(ProviderV2.ID.make("venice"), ModelV2.ID.make("alias")),
  111. api: { id: ModelV2.ID.make("alias"), type: "aisdk", package: "test-provider" },
  112. }),
  113. sdk: fakeSelectorSdk(calls),
  114. options: {},
  115. },
  116. {},
  117. )
  118. expect(calls).toEqual([])
  119. expect(result.language).toBeUndefined()
  120. }),
  121. )
  122. })