boot.ts 2.8 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495
  1. export * as PluginBoot from "./boot"
  2. import { Context, Deferred, Effect, Layer } from "effect"
  3. import { AccountV2 } from "../account"
  4. import { AgentV2 } from "../agent"
  5. import { Catalog } from "../catalog"
  6. import { Config } from "../config"
  7. import { ConfigAgentPlugin } from "../config/plugin/agent"
  8. import { EventV2 } from "../event"
  9. import { Npm } from "../npm"
  10. import { PluginV2 } from "../plugin"
  11. import { AccountPlugin } from "./account"
  12. import { ConfigProviderPlugin } from "../config/plugin/provider"
  13. import { EnvPlugin } from "./env"
  14. import { ModelsDevPlugin } from "./models-dev"
  15. import { ProviderPlugins } from "./provider"
  16. type Plugin = {
  17. id: PluginV2.ID
  18. effect: PluginV2.Effect<
  19. | Catalog.Service
  20. | AccountV2.Service
  21. | AgentV2.Service
  22. | Npm.Service
  23. | EventV2.Service
  24. | PluginV2.Service
  25. | Config.Service
  26. >
  27. }
  28. export interface Interface {
  29. readonly wait: () => Effect.Effect<void>
  30. }
  31. export class Service extends Context.Service<Service, Interface>()("@opencode/v2/PluginBoot") {}
  32. export const layer = Layer.effect(
  33. Service,
  34. Effect.gen(function* () {
  35. const catalog = yield* Catalog.Service
  36. const plugin = yield* PluginV2.Service
  37. const accounts = yield* AccountV2.Service
  38. const agents = yield* AgentV2.Service
  39. const config = yield* Config.Service
  40. const npm = yield* Npm.Service
  41. const events = yield* EventV2.Service
  42. const done = yield* Deferred.make<void>()
  43. const add = Effect.fn("PluginBoot.add")(function* (input: Plugin) {
  44. yield* plugin.add({
  45. id: input.id,
  46. effect: input.effect.pipe(
  47. Effect.provideService(Catalog.Service, catalog),
  48. Effect.provideService(AccountV2.Service, accounts),
  49. Effect.provideService(AgentV2.Service, agents),
  50. Effect.provideService(Config.Service, config),
  51. Effect.provideService(Npm.Service, npm),
  52. Effect.provideService(EventV2.Service, events),
  53. Effect.provideService(PluginV2.Service, plugin),
  54. ),
  55. })
  56. })
  57. const boot = Effect.gen(function* () {
  58. yield* add(EnvPlugin)
  59. yield* add(AccountPlugin)
  60. for (const item of ProviderPlugins) {
  61. yield* add(item)
  62. }
  63. yield* add(ModelsDevPlugin)
  64. yield* add(ConfigProviderPlugin.Plugin)
  65. yield* add(ConfigAgentPlugin.Plugin)
  66. }).pipe(Effect.withSpan("PluginBoot.boot"))
  67. yield* boot.pipe(
  68. Effect.exit,
  69. Effect.flatMap((exit) => Deferred.done(done, exit)),
  70. Effect.forkScoped,
  71. )
  72. return Service.of({
  73. wait: () => Deferred.await(done),
  74. })
  75. }),
  76. )
  77. export const defaultLayer = layer.pipe(
  78. Layer.provide(Catalog.defaultLayer),
  79. Layer.provide(EventV2.defaultLayer),
  80. Layer.provide(PluginV2.defaultLayer),
  81. Layer.provide(AccountV2.defaultLayer),
  82. Layer.provide(AgentV2.defaultLayer),
  83. Layer.provide(Config.defaultLayer),
  84. Layer.provide(Npm.defaultLayer),
  85. )