opencode.ts 1.8 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647
  1. import { OpenCode } from "@opencode-ai/client/effect"
  2. import { PermissionSaved } from "@opencode-ai/core/permission/saved"
  3. import { ApplicationTools } from "@opencode-ai/core/tool/application-tools"
  4. import { createEmbeddedRoutes } from "@opencode-ai/server/routes"
  5. import { Context, Effect, Layer, Scope } from "effect"
  6. import { FetchHttpClient, HttpRouter, HttpServer } from "effect/unstable/http"
  7. export const create = Effect.fn("OpenCode.create")(function* () {
  8. const scope = yield* Scope.Scope
  9. const memoMap = yield* Layer.makeMemoMap
  10. const context = yield* Layer.buildWithMemoMap(
  11. Layer.merge(ApplicationTools.layer, PermissionSaved.defaultLayer),
  12. memoMap,
  13. scope,
  14. )
  15. const tools = Context.get(context, ApplicationTools.Service)
  16. const permissions = Context.get(context, PermissionSaved.Service)
  17. const web = yield* Effect.acquireRelease(
  18. Effect.sync(() =>
  19. HttpRouter.toWebHandler(
  20. createEmbeddedRoutes().pipe(
  21. HttpRouter.provideRequest(Layer.succeed(PermissionSaved.Service, permissions)),
  22. Layer.provide(HttpServer.layerServices),
  23. ),
  24. { disableLogger: true, memoMap },
  25. ),
  26. ),
  27. (web) => Effect.promise(web.dispose),
  28. )
  29. const fetch = Object.assign((input: RequestInfo | URL, init?: RequestInit) => web.handler(new Request(input, init)), {
  30. preconnect: () => undefined,
  31. }) satisfies typeof globalThis.fetch
  32. const client = yield* OpenCode.make({ baseUrl: "http://opencode.local" }).pipe(
  33. Effect.provide(FetchHttpClient.layer),
  34. Effect.provideService(FetchHttpClient.Fetch, fetch),
  35. )
  36. return {
  37. ...client,
  38. tools: { register: tools.register },
  39. }
  40. })
  41. export type Interface = Effect.Success<ReturnType<typeof create>>
  42. export class Service extends Context.Service<Service, Interface>()("@opencode-ai/sdk-next/OpenCode") {}
  43. export const layer = Layer.effect(Service, create())