import { Context, Effect, Layer, Stream } from "effect" import { RequestExecutor } from "./route/executor.js" import type { AIError } from "./schema/index.js" import { responseEvents, type ImageEvent, type ImageOptions, type ImageRequestFor, type ImageResponse, } from "./image.js" export interface Interface { readonly generate: ( request: ImageRequestFor, ) => Effect.Effect readonly stream: ( request: ImageRequestFor, ) => Stream.Stream } export class Service extends Context.Service()("@opencode/ImageClient") {} export const generate = ( request: ImageRequestFor, ): Effect.Effect => Effect.gen(function* () { const client = yield* Service return yield* client.generate(request) }) export const stream = ( request: ImageRequestFor, ): Stream.Stream => Stream.unwrap( Effect.gen(function* () { const client = yield* Service return client.stream(request) }), ) export const layer: Layer.Layer = Layer.effect( Service, Effect.gen(function* () { const executor = yield* RequestExecutor.Service const generate = (request: ImageRequestFor) => request.model.route.generate(request, executor.execute) return Service.of({ generate, // Inline routes have no partial frames yet; the stream is the completed response expanded into events. stream: (request) => Stream.unwrap(generate(request).pipe(Effect.map((response) => Stream.fromIterable(responseEvents(response))))), }) }), ) export const ImageClient = { Service, layer, generate, stream, } as const