models-dev.test.ts 3.0 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283
  1. import path from "path"
  2. import { describe, expect } from "bun:test"
  3. import { Effect, Layer } from "effect"
  4. import { Catalog } from "@opencode-ai/core/catalog"
  5. import { Integration } from "@opencode-ai/core/integration"
  6. import { Credential } from "@opencode-ai/core/credential"
  7. import { Database } from "@opencode-ai/core/database/database"
  8. import { EventV2 } from "@opencode-ai/core/event"
  9. import { Flag } from "@opencode-ai/core/flag/flag"
  10. import { Location } from "@opencode-ai/core/location"
  11. import { ModelsDev } from "@opencode-ai/core/models-dev"
  12. import { PluginV2 } from "@opencode-ai/core/plugin"
  13. import { ModelsDevPlugin } from "@opencode-ai/core/plugin/models-dev"
  14. import { Policy } from "@opencode-ai/core/policy"
  15. import { AbsolutePath } from "@opencode-ai/core/schema"
  16. import { location } from "../fixture/location"
  17. import { testEffect } from "../lib/effect"
  18. const events = EventV2.defaultLayer
  19. const locationLayer = Layer.succeed(
  20. Location.Service,
  21. Location.Service.of(location({ directory: AbsolutePath.make(import.meta.dir) })),
  22. )
  23. const plugins = PluginV2.layer.pipe(Layer.provide(events))
  24. const policy = Policy.layer.pipe(Layer.provide(locationLayer))
  25. const connections = Credential.layer.pipe(
  26. Layer.fresh,
  27. Layer.provide(Database.layerFromPath(":memory:").pipe(Layer.fresh)),
  28. Layer.provide(events),
  29. )
  30. const integrations = Integration.locationLayer.pipe(Layer.provide(events), Layer.provide(connections))
  31. const catalog = Catalog.layer.pipe(
  32. Layer.provide(Layer.mergeAll(events, locationLayer, plugins, policy, connections, integrations)),
  33. )
  34. const layer = Layer.mergeAll(
  35. catalog.pipe(Layer.provide(connections)),
  36. integrations,
  37. connections,
  38. events,
  39. locationLayer,
  40. plugins,
  41. )
  42. const it = testEffect(layer)
  43. describe("ModelsDevPlugin", () => {
  44. it.effect("registers key methods for providers with environment variables", () =>
  45. Effect.acquireUseRelease(
  46. Effect.sync(() => {
  47. const previous = {
  48. path: Flag.OPENCODE_MODELS_PATH,
  49. disabled: Flag.OPENCODE_DISABLE_MODELS_FETCH,
  50. }
  51. Flag.OPENCODE_MODELS_PATH = path.join(import.meta.dir, "fixtures", "models-dev.json")
  52. Flag.OPENCODE_DISABLE_MODELS_FETCH = true
  53. return previous
  54. }),
  55. () =>
  56. Effect.gen(function* () {
  57. yield* ModelsDevPlugin.effect
  58. const integrations = yield* Integration.Service
  59. expect(yield* integrations.list()).toEqual([
  60. new Integration.Info({
  61. id: Integration.ID.make("acme"),
  62. name: "Acme",
  63. methods: [
  64. { type: "key" },
  65. {
  66. type: "env",
  67. names: ["ACME_API_KEY"],
  68. },
  69. ],
  70. connections: [],
  71. }),
  72. ])
  73. }).pipe(Effect.provide(ModelsDev.defaultLayer)),
  74. (previous) =>
  75. Effect.sync(() => {
  76. Flag.OPENCODE_MODELS_PATH = previous.path
  77. Flag.OPENCODE_DISABLE_MODELS_FETCH = previous.disabled
  78. }),
  79. ),
  80. )
  81. })