provider-zenmux.test.ts 4.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118
  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 { ProviderPlugins } from "@opencode-ai/core/plugin/provider"
  6. import { ZenmuxPlugin } from "@opencode-ai/core/plugin/provider/zenmux"
  7. import { ProviderV2 } from "@opencode-ai/core/provider"
  8. import { expectPluginRegistered, it, provider } from "./provider-helper"
  9. describe("ZenmuxPlugin", () => {
  10. it.effect("is registered so legacy referer headers can be applied", () =>
  11. Effect.sync(() =>
  12. expectPluginRegistered(
  13. ProviderPlugins.map((item) => item.id),
  14. "zenmux",
  15. ),
  16. ),
  17. )
  18. it.effect("applies the exact legacy Zenmux headers", () =>
  19. Effect.gen(function* () {
  20. const plugin = yield* PluginV2.Service
  21. const catalog = yield* Catalog.Service
  22. yield* plugin.add(ZenmuxPlugin)
  23. const load = yield* catalog.loader()
  24. yield* load((catalog) => {
  25. const item = provider("zenmux", {
  26. endpoint: { type: "aisdk", package: "@ai-sdk/openai-compatible", url: "https://zenmux.ai/api/v1" },
  27. })
  28. catalog.provider.update(item.id, (draft) => {
  29. draft.endpoint = item.endpoint
  30. })
  31. })
  32. const result = yield* catalog.provider.get(ProviderV2.ID.make("zenmux"))
  33. expect(result.options.headers).toEqual({ "HTTP-Referer": "https://opencode.ai/", "X-Title": "opencode" })
  34. expect(Object.keys(result.options.headers).sort()).toEqual(["HTTP-Referer", "X-Title"])
  35. }),
  36. )
  37. it.effect("merges legacy Zenmux headers with existing headers", () =>
  38. Effect.gen(function* () {
  39. const plugin = yield* PluginV2.Service
  40. const catalog = yield* Catalog.Service
  41. yield* plugin.add(ZenmuxPlugin)
  42. const load = yield* catalog.loader()
  43. yield* load((catalog) => {
  44. const item = provider("zenmux", {
  45. endpoint: { type: "aisdk", package: "@ai-sdk/openai-compatible", url: "https://zenmux.ai/api/v1" },
  46. options: { headers: { Existing: "value" }, body: {}, aisdk: { provider: {}, request: {} } },
  47. })
  48. catalog.provider.update(item.id, (draft) => {
  49. draft.endpoint = item.endpoint
  50. draft.options = item.options
  51. })
  52. })
  53. expect((yield* catalog.provider.get(ProviderV2.ID.make("zenmux"))).options.headers).toEqual({
  54. Existing: "value",
  55. "HTTP-Referer": "https://opencode.ai/",
  56. "X-Title": "opencode",
  57. })
  58. }),
  59. )
  60. it.effect("lets configured Zenmux legacy headers override defaults", () =>
  61. Effect.gen(function* () {
  62. const plugin = yield* PluginV2.Service
  63. const catalog = yield* Catalog.Service
  64. yield* plugin.add(ZenmuxPlugin)
  65. const load = yield* catalog.loader()
  66. yield* load((catalog) => {
  67. const item = provider("zenmux", {
  68. endpoint: { type: "aisdk", package: "@ai-sdk/openai-compatible", url: "https://zenmux.ai/api/v1" },
  69. options: {
  70. headers: { "HTTP-Referer": "https://example.com/", "X-Title": "custom-title" },
  71. body: {},
  72. aisdk: { provider: {}, request: {} },
  73. },
  74. })
  75. catalog.provider.update(item.id, (draft) => {
  76. draft.endpoint = item.endpoint
  77. draft.options = item.options
  78. })
  79. })
  80. expect((yield* catalog.provider.get(ProviderV2.ID.make("zenmux"))).options.headers).toEqual({
  81. "HTTP-Referer": "https://example.com/",
  82. "X-Title": "custom-title",
  83. })
  84. }),
  85. )
  86. it.effect("guards legacy Zenmux headers to the exact zenmux provider id", () =>
  87. Effect.gen(function* () {
  88. const plugin = yield* PluginV2.Service
  89. const catalog = yield* Catalog.Service
  90. yield* plugin.add(ZenmuxPlugin)
  91. const load = yield* catalog.loader()
  92. yield* load((catalog) => {
  93. const item = provider("openrouter", {
  94. options: {
  95. headers: { "HTTP-Referer": "https://example.com/", "X-Title": "custom-title" },
  96. body: {},
  97. aisdk: { provider: {}, request: {} },
  98. },
  99. })
  100. catalog.provider.update(item.id, (draft) => {
  101. draft.options = item.options
  102. })
  103. })
  104. expect((yield* catalog.provider.get(ProviderV2.ID.openrouter)).options.headers).toEqual({
  105. "HTTP-Referer": "https://example.com/",
  106. "X-Title": "custom-title",
  107. })
  108. }),
  109. )
  110. })