@opencode-ai/ai
Advanced tools
| import { Context, Effect, Layer } from "effect"; | ||
| import { RequestExecutor } from "./route/executor"; | ||
| import type { ImageRequest, ImageResponse } from "./image"; | ||
| import type { ImageOptions, ImageRequestFor, ImageResponse } from "./image"; | ||
| import type { LLMError } from "./schema"; | ||
| export type Execute = RequestExecutor.Interface["execute"]; | ||
| export interface Interface { | ||
| readonly generate: (request: ImageRequest) => Effect.Effect<ImageResponse, LLMError>; | ||
| readonly generate: <Options extends ImageOptions>(request: ImageRequestFor<Options>) => Effect.Effect<ImageResponse, LLMError>; | ||
| } | ||
@@ -12,3 +12,3 @@ declare const Service_base: Context.ServiceClass<Service, "@opencode/ImageClient", Interface>; | ||
| } | ||
| export declare const generate: (request: ImageRequest) => Effect.Effect<ImageResponse, LLMError>; | ||
| export declare const generate: <Options extends ImageOptions>(request: ImageRequestFor<Options>) => Effect.Effect<ImageResponse, LLMError>; | ||
| export declare const layer: Layer.Layer<Service, never, RequestExecutor.Service>; | ||
@@ -18,4 +18,4 @@ export declare const ImageClient: { | ||
| readonly layer: Layer.Layer<Service, never, RequestExecutor.Service>; | ||
| readonly generate: (request: ImageRequest) => Effect.Effect<ImageResponse, LLMError>; | ||
| readonly generate: <Options extends ImageOptions>(request: ImageRequestFor<Options>) => Effect.Effect<ImageResponse, LLMError>; | ||
| }; | ||
| export {}; |
+33
-38
| import { Effect, Schema } from "effect"; | ||
| import { HttpOptions, LLMError, ModelID, ProviderID, Usage } from "./schema"; | ||
| import { type Execute as ImageExecute } from "./image-client"; | ||
| export interface ImageRoute { | ||
| import { Service, type Execute as ImageExecute } from "./image-client"; | ||
| export interface ImageRoute<Options extends ImageOptions = ImageOptions> { | ||
| readonly id: string; | ||
| readonly generate: (request: ImageRequest, execute: ImageExecute) => Effect.Effect<ImageResponse, LLMError>; | ||
| readonly generate: (request: ImageRequestFor<Options>, execute: ImageExecute) => Effect.Effect<ImageResponse, LLMError>; | ||
| } | ||
| export declare class ImageModel { | ||
| export type ImageOptions = Record<string, unknown>; | ||
| export declare class ImageModel<Options extends ImageOptions = ImageOptions> { | ||
| protected readonly _Options: (options: Options) => Options; | ||
| readonly id: ModelID; | ||
| readonly provider: ProviderID; | ||
| readonly route: ImageRoute; | ||
| readonly defaults?: ImageModelDefaults; | ||
| constructor(input: ImageModel.Input); | ||
| static make(input: ImageModel.MakeInput): ImageModel; | ||
| readonly route: ImageRoute<Options>; | ||
| readonly http?: HttpOptions; | ||
| constructor(input: ImageModel.Input<Options>); | ||
| static make<Options extends ImageOptions = ImageOptions>(input: ImageModel.MakeInput<Options>): ImageModel<Options>; | ||
| } | ||
| export declare namespace ImageModel { | ||
| interface Input { | ||
| interface Input<Options extends ImageOptions = ImageOptions> { | ||
| readonly id: ModelID; | ||
| readonly provider: ProviderID; | ||
| readonly route: ImageRoute; | ||
| readonly defaults?: ImageModelDefaults; | ||
| readonly route: ImageRoute<Options>; | ||
| readonly http?: HttpOptions; | ||
| } | ||
| interface MakeInput extends Omit<Input, "id" | "provider"> { | ||
| interface MakeInput<Options extends ImageOptions = ImageOptions> extends Omit<Input<Options>, "id" | "provider"> { | ||
| readonly id: string | ModelID; | ||
@@ -28,31 +30,22 @@ readonly provider: string | ProviderID; | ||
| } | ||
| export interface ImageModelDefaults { | ||
| readonly providerOptions?: Record<string, Record<string, unknown>>; | ||
| readonly http?: HttpOptions; | ||
| } | ||
| export declare const ImageModelSchema: Schema.declare<ImageModel, ImageModel>; | ||
| export declare const ImageSize: Schema.Struct<{ | ||
| readonly width: Schema.Int; | ||
| readonly height: Schema.Int; | ||
| }>; | ||
| export type ImageSize = Schema.Schema.Type<typeof ImageSize>; | ||
| export declare const ImageModelSchema: Schema.declare<ImageModel<ImageOptions>, ImageModel<ImageOptions>>; | ||
| declare const ImageRequest_base: Schema.Class<ImageRequest, Schema.Struct<{ | ||
| readonly model: Schema.declare<ImageModel, ImageModel>; | ||
| readonly model: Schema.declare<ImageModel<ImageOptions>, ImageModel<ImageOptions>>; | ||
| readonly prompt: Schema.String; | ||
| readonly count: Schema.optional<Schema.Int>; | ||
| readonly size: Schema.optional<Schema.Struct<{ | ||
| readonly width: Schema.Int; | ||
| readonly height: Schema.Int; | ||
| }>>; | ||
| readonly aspectRatio: Schema.optional<Schema.String>; | ||
| readonly seed: Schema.optional<Schema.Number>; | ||
| readonly providerOptions: Schema.optional<Schema.$Record<Schema.String, Schema.$Record<Schema.String, Schema.Unknown>>>; | ||
| readonly options: Schema.optional<Schema.$Record<Schema.String, Schema.Unknown>>; | ||
| readonly http: Schema.optional<typeof HttpOptions>; | ||
| readonly metadata: Schema.optional<Schema.$Record<Schema.String, Schema.Unknown>>; | ||
| }>, {}>; | ||
| export declare class ImageRequest extends ImageRequest_base { | ||
| protected readonly _ImageRequest: void; | ||
| } | ||
| export type ImageRequestInput = Omit<ConstructorParameters<typeof ImageRequest>[0], "http"> & { | ||
| export type ImageRequestFor<Options extends ImageOptions = ImageOptions> = Omit<ImageRequest, "model" | "options"> & { | ||
| readonly model: ImageModel<Options>; | ||
| readonly options?: Options; | ||
| }; | ||
| export type ImageModelOptions<Model> = Model extends ImageModel<infer Options> ? Options : never; | ||
| export type ImageRequestInput<Model extends object = ImageModel> = Omit<ConstructorParameters<typeof ImageRequest>[0], "model" | "options" | "http"> & { | ||
| readonly model: Model; | ||
| readonly options?: NoInfer<ImageModelOptions<Model>>; | ||
| readonly http?: HttpOptions.Input; | ||
| }; | ||
| } & (Model extends ImageModel<ImageModelOptions<Model>> ? unknown : never); | ||
| declare const GeneratedImage_base: Schema.Class<GeneratedImage, Schema.Struct<{ | ||
@@ -73,8 +66,10 @@ readonly mediaType: Schema.String; | ||
| } | ||
| export declare const request: (input: ImageRequest | ImageRequestInput) => ImageRequest; | ||
| export declare const generate: (input: ImageRequest | ImageRequestInput) => Effect.Effect<ImageResponse, LLMError, never>; | ||
| export declare function request<const Model extends object>(input: ImageRequestInput<Model>): ImageRequestFor<ImageModelOptions<Model>>; | ||
| export declare function request(input: ImageRequest): ImageRequest; | ||
| export declare function generate<const Model extends object>(input: ImageRequestInput<Model>): Effect.Effect<ImageResponse, LLMError, Service>; | ||
| export declare function generate(input: ImageRequest): Effect.Effect<ImageResponse, LLMError, Service>; | ||
| export declare const Image: { | ||
| readonly request: (input: ImageRequest | ImageRequestInput) => ImageRequest; | ||
| readonly generate: (input: ImageRequest | ImageRequestInput) => Effect.Effect<ImageResponse, LLMError, never>; | ||
| readonly request: typeof request; | ||
| readonly generate: typeof generate; | ||
| }; | ||
| export {}; |
+18
-24
| import { Effect, Schema } from "effect"; | ||
| import { HttpOptions, InvalidRequestReason, LLMError, ModelID, ProviderID, ProviderMetadata, Usage } from "./schema"; | ||
| import { ImageClient } from "./image-client"; | ||
| import { ImageClient, Service } from "./image-client"; | ||
| export class ImageModel { | ||
@@ -8,3 +8,3 @@ id; | ||
| route; | ||
| defaults; | ||
| http; | ||
| constructor(input) { | ||
@@ -14,3 +14,3 @@ this.id = input.id; | ||
| this.route = input.route; | ||
| this.defaults = input.defaults; | ||
| this.http = input.http; | ||
| } | ||
@@ -22,3 +22,3 @@ static make(input) { | ||
| route: input.route, | ||
| defaults: input.defaults, | ||
| http: input.http, | ||
| }); | ||
@@ -30,16 +30,7 @@ } | ||
| }); | ||
| export const ImageSize = Schema.Struct({ | ||
| width: Schema.Int.check(Schema.isGreaterThanOrEqualTo(1)), | ||
| height: Schema.Int.check(Schema.isGreaterThanOrEqualTo(1)), | ||
| }).annotate({ identifier: "Image.Size" }); | ||
| export class ImageRequest extends Schema.Class("Image.Request")({ | ||
| model: ImageModelSchema, | ||
| prompt: Schema.String, | ||
| count: Schema.optional(Schema.Int.check(Schema.isGreaterThanOrEqualTo(1))), | ||
| size: Schema.optional(ImageSize), | ||
| aspectRatio: Schema.optional(Schema.String), | ||
| seed: Schema.optional(Schema.Number), | ||
| providerOptions: Schema.optional(Schema.Record(Schema.String, Schema.Record(Schema.String, Schema.Unknown))), | ||
| options: Schema.optional(Schema.Record(Schema.String, Schema.Unknown)), | ||
| http: Schema.optional(HttpOptions), | ||
| metadata: Schema.optional(Schema.Record(Schema.String, Schema.Unknown)), | ||
| }) { | ||
@@ -62,3 +53,3 @@ } | ||
| } | ||
| export const request = (input) => { | ||
| export function request(input) { | ||
| if (input instanceof ImageRequest) | ||
@@ -68,13 +59,16 @@ return input; | ||
| ...input, | ||
| model: input.model, | ||
| http: input.http === undefined ? undefined : HttpOptions.make(input.http), | ||
| }); | ||
| }; | ||
| export const generate = (input) => Effect.try({ | ||
| try: () => request(input), | ||
| catch: (error) => new LLMError({ | ||
| module: "Image", | ||
| method: "generate", | ||
| reason: new InvalidRequestReason({ message: error instanceof Error ? error.message : String(error) }), | ||
| }), | ||
| }).pipe(Effect.flatMap(ImageClient.generate)); | ||
| } | ||
| export function generate(input) { | ||
| return Effect.try({ | ||
| try: () => (input instanceof ImageRequest ? input : request(input)), | ||
| catch: (error) => new LLMError({ | ||
| module: "Image", | ||
| method: "generate", | ||
| reason: new InvalidRequestReason({ message: error instanceof Error ? error.message : String(error) }), | ||
| }), | ||
| }).pipe(Effect.flatMap((request) => ImageClient.generate(request))); | ||
| } | ||
| export const Image = { | ||
@@ -81,0 +75,0 @@ request, |
+2
-2
@@ -9,4 +9,4 @@ export { LLMClient } from "./route/client"; | ||
| export * from "./schema"; | ||
| export { GeneratedImage, ImageModel, ImageRequest, ImageResponse, ImageSize } from "./image"; | ||
| export type { ImageModelDefaults, ImageRequestInput, ImageRoute } from "./image"; | ||
| export { GeneratedImage, ImageModel, ImageRequest, ImageResponse } from "./image"; | ||
| export type { ImageModelOptions, ImageOptions, ImageRequestFor, ImageRequestInput, ImageRoute } from "./image"; | ||
| export { Image } from "./image"; | ||
@@ -13,0 +13,0 @@ export { Tool, ToolFailure, toDefinitions } from "./tool"; |
+1
-1
@@ -8,3 +8,3 @@ export { LLMClient } from "./route/client"; | ||
| export * from "./schema"; | ||
| export { GeneratedImage, ImageModel, ImageRequest, ImageResponse, ImageSize } from "./image"; | ||
| export { GeneratedImage, ImageModel, ImageRequest, ImageResponse } from "./image"; | ||
| export { Image } from "./image"; | ||
@@ -11,0 +11,0 @@ export { Tool, ToolFailure, toDefinitions } from "./tool"; |
@@ -73,10 +73,10 @@ import { Route, type RouteRoutedModelInput } from "../route/client"; | ||
| readonly type: "image_generation"; | ||
| readonly size?: string | undefined; | ||
| readonly quality?: "low" | "medium" | "high" | "auto" | undefined; | ||
| readonly background?: "auto" | "opaque" | "transparent" | undefined; | ||
| readonly output_format?: "png" | "jpeg" | "webp" | undefined; | ||
| readonly output_compression?: number | undefined; | ||
| readonly action?: "generate" | "auto" | "edit" | undefined; | ||
| readonly background?: "auto" | "opaque" | "transparent" | undefined; | ||
| readonly input_fidelity?: "low" | "high" | undefined; | ||
| readonly partial_images?: number | undefined; | ||
| readonly quality?: "low" | "medium" | "high" | "auto" | undefined; | ||
| readonly size?: string | undefined; | ||
| })[] | undefined; | ||
@@ -83,0 +83,0 @@ readonly temperature?: number | undefined; |
@@ -1,25 +0,20 @@ | ||
| import { Schema } from "effect"; | ||
| import { ImageModel, type ImageModelDefaults } from "../image"; | ||
| import { ImageModel } from "../image"; | ||
| import { type Definition as AuthDefinition } from "../route/auth"; | ||
| import { type HttpOptions } from "../schema"; | ||
| export declare const DEFAULT_BASE_URL = "https://api.openai.com/v1"; | ||
| export declare const PATH = "/images/generations"; | ||
| export interface OpenAIImageOptions { | ||
| readonly quality?: "auto" | "low" | "medium" | "high"; | ||
| readonly background?: "auto" | "opaque" | "transparent"; | ||
| readonly moderation?: "auto" | "low"; | ||
| readonly outputFormat?: "png" | "jpeg" | "webp"; | ||
| export type OpenAIImageString<Known extends string> = Known | (string & {}); | ||
| export type OpenAIImageOptions = { | ||
| readonly n?: number; | ||
| readonly size?: OpenAIImageString<"auto" | "256x256" | "512x512" | "1024x1024" | "1536x1024" | "1024x1536" | "1792x1024" | "1024x1792">; | ||
| readonly quality?: OpenAIImageString<"auto" | "low" | "medium" | "high" | "standard" | "hd">; | ||
| readonly background?: OpenAIImageString<"auto" | "opaque" | "transparent">; | ||
| readonly moderation?: OpenAIImageString<"auto" | "low">; | ||
| readonly outputFormat?: OpenAIImageString<"png" | "jpeg" | "webp">; | ||
| readonly outputCompression?: number; | ||
| } | ||
| declare const OpenAIImageBody: Schema.Struct<{ | ||
| readonly model: Schema.String; | ||
| readonly prompt: Schema.String; | ||
| readonly n: Schema.optional<Schema.Int>; | ||
| readonly size: Schema.optional<Schema.String>; | ||
| readonly quality: Schema.optional<Schema.Literals<readonly ["auto", "low", "medium", "high"]>>; | ||
| readonly background: Schema.optional<Schema.Literals<readonly ["auto", "opaque", "transparent"]>>; | ||
| readonly moderation: Schema.optional<Schema.Literals<readonly ["auto", "low"]>>; | ||
| readonly output_format: Schema.optional<Schema.Literals<readonly ["png", "jpeg", "webp"]>>; | ||
| readonly output_compression: Schema.optional<Schema.Int>; | ||
| }>; | ||
| export type OpenAIImageBody = Schema.Schema.Type<typeof OpenAIImageBody>; | ||
| } & Record<string, unknown>; | ||
| export type OpenAIImageBody = Record<string, unknown> & { | ||
| readonly model: string; | ||
| readonly prompt: string; | ||
| }; | ||
| export interface ModelInput { | ||
@@ -30,8 +25,7 @@ readonly id: string; | ||
| readonly headers?: Record<string, string>; | ||
| readonly defaults?: ImageModelDefaults; | ||
| readonly http?: HttpOptions; | ||
| } | ||
| export declare const model: (input: ModelInput) => ImageModel; | ||
| export declare const model: (input: ModelInput) => ImageModel<OpenAIImageOptions>; | ||
| export declare const OpenAIImages: { | ||
| readonly model: (input: ModelInput) => ImageModel; | ||
| readonly model: (input: ModelInput) => ImageModel<OpenAIImageOptions>; | ||
| }; | ||
| export {}; |
| import { Effect, Encoding, Schema } from "effect"; | ||
| import { Headers, HttpClientRequest } from "effect/unstable/http"; | ||
| import { ImageModel, GeneratedImage, ImageResponse, } from "../image"; | ||
| import { ImageModel, GeneratedImage, ImageResponse } from "../image"; | ||
| import { Auth } from "../route/auth"; | ||
| import { InvalidProviderOutputReason, LLMError, Usage, mergeHttpOptions, mergeJsonRecords } from "../schema"; | ||
| import { InvalidProviderOutputReason, LLMError, Usage, mergeHttpOptions, mergeJsonRecords, } from "../schema"; | ||
| import { ProviderShared } from "./shared"; | ||
@@ -11,13 +11,2 @@ import { OpenAIImage } from "./utils/openai-image"; | ||
| export const PATH = "/images/generations"; | ||
| const OpenAIImageBody = Schema.Struct({ | ||
| model: Schema.String, | ||
| prompt: Schema.String, | ||
| n: Schema.optional(Schema.Int.check(Schema.isGreaterThanOrEqualTo(1))), | ||
| size: Schema.optional(Schema.String), | ||
| quality: Schema.optional(Schema.Literals(["auto", "low", "medium", "high"])), | ||
| background: Schema.optional(Schema.Literals(["auto", "opaque", "transparent"])), | ||
| moderation: Schema.optional(Schema.Literals(["auto", "low"])), | ||
| output_format: Schema.optional(Schema.Literals(["png", "jpeg", "webp"])), | ||
| output_compression: Schema.optional(Schema.Int.check(Schema.isBetween({ minimum: 0, maximum: 100 }))), | ||
| }); | ||
| const OpenAIImageResponse = Schema.Struct({ | ||
@@ -38,18 +27,10 @@ data: Schema.Array(Schema.Struct({ | ||
| }); | ||
| const providerOptions = (request) => ({ | ||
| ...request.model.defaults?.providerOptions?.openai, | ||
| ...request.providerOptions?.openai, | ||
| }); | ||
| const body = (request) => { | ||
| const options = providerOptions(request); | ||
| const nativeOptions = (options) => { | ||
| if (!options) | ||
| return undefined; | ||
| const { outputFormat, outputCompression, ...native } = options; | ||
| return { | ||
| model: request.model.id, | ||
| prompt: request.prompt, | ||
| n: request.count, | ||
| size: request.size === undefined ? undefined : `${request.size.width}x${request.size.height}`, | ||
| quality: options.quality, | ||
| background: options.background, | ||
| moderation: options.moderation, | ||
| output_format: options.outputFormat, | ||
| output_compression: options.outputCompression, | ||
| output_format: outputFormat, | ||
| output_compression: outputCompression, | ||
| ...native, | ||
| }; | ||
@@ -69,21 +50,2 @@ }; | ||
| }; | ||
| const PROTOCOL_BODY_FIELDS = new Set([ | ||
| "model", | ||
| "prompt", | ||
| "n", | ||
| "size", | ||
| "quality", | ||
| "background", | ||
| "moderation", | ||
| "output_format", | ||
| "output_compression", | ||
| ]); | ||
| const bodyWithOverlay = Effect.fn("OpenAIImages.bodyWithOverlay")(function* (imageBody, overlay) { | ||
| if (!overlay) | ||
| return imageBody; | ||
| const reserved = Object.keys(overlay).filter((key) => PROTOCOL_BODY_FIELDS.has(key)); | ||
| if (reserved.length > 0) | ||
| return yield* ProviderShared.invalidRequest(`http.body cannot overlay protocol-owned field(s): ${reserved.join(", ")}`); | ||
| return mergeJsonRecords(imageBody, overlay) ?? imageBody; | ||
| }); | ||
| export const model = (input) => { | ||
@@ -93,10 +55,5 @@ const route = { | ||
| generate: Effect.fn("OpenAIImages.generate")(function* (request, execute) { | ||
| if (request.aspectRatio !== undefined) | ||
| return yield* ProviderShared.invalidRequest("OpenAI Images does not support the common aspectRatio option"); | ||
| if (request.seed !== undefined) | ||
| return yield* ProviderShared.invalidRequest("OpenAI Images does not support the common seed option"); | ||
| const requestBody = yield* ProviderShared.validateWith(Schema.decodeUnknownEffect(OpenAIImageBody))(body(request)); | ||
| const http = mergeHttpOptions(request.model.defaults?.http, request.http); | ||
| const overlaidBody = yield* bodyWithOverlay(requestBody, http?.body); | ||
| const text = ProviderShared.encodeJson(overlaidBody); | ||
| const http = mergeHttpOptions(request.model.http, request.http); | ||
| const requestBody = mergeJsonRecords({ model: request.model.id, prompt: request.prompt }, nativeOptions(request.options), http?.body); | ||
| const text = ProviderShared.encodeJson(requestBody); | ||
| const url = applyQuery(`${(input.baseURL ?? DEFAULT_BASE_URL).replace(/\/$/, "")}${PATH}`, http?.query); | ||
@@ -113,3 +70,3 @@ const headers = yield* Auth.toEffect(input.auth)({ | ||
| const decoded = yield* Schema.decodeUnknownEffect(OpenAIImageResponse)(payload).pipe(Effect.mapError(() => invalidOutput("OpenAI Images returned an invalid response"))); | ||
| const format = decoded.output_format ?? providerOptions(request).outputFormat ?? "png"; | ||
| const format = decoded.output_format ?? (typeof requestBody.output_format === "string" ? requestBody.output_format : "png"); | ||
| const images = yield* Effect.forEach(decoded.data, (item, index) => { | ||
@@ -146,3 +103,3 @@ if (item.b64_json) | ||
| }; | ||
| return ImageModel.make({ id: input.id, provider: "openai", route, defaults: input.defaults }); | ||
| return ImageModel.make({ id: input.id, provider: "openai", route, http: input.http }); | ||
| }; | ||
@@ -149,0 +106,0 @@ export const OpenAIImages = { |
@@ -167,10 +167,10 @@ import { Schema } from "effect"; | ||
| readonly type: "image_generation"; | ||
| readonly size?: string | undefined; | ||
| readonly quality?: "low" | "medium" | "high" | "auto" | undefined; | ||
| readonly background?: "auto" | "opaque" | "transparent" | undefined; | ||
| readonly output_format?: "png" | "jpeg" | "webp" | undefined; | ||
| readonly output_compression?: number | undefined; | ||
| readonly action?: "generate" | "auto" | "edit" | undefined; | ||
| readonly background?: "auto" | "opaque" | "transparent" | undefined; | ||
| readonly input_fidelity?: "low" | "high" | undefined; | ||
| readonly partial_images?: number | undefined; | ||
| readonly quality?: "low" | "medium" | "high" | "auto" | undefined; | ||
| readonly size?: string | undefined; | ||
| })[] | undefined; | ||
@@ -320,10 +320,10 @@ readonly temperature?: number | undefined; | ||
| readonly type: "image_generation"; | ||
| readonly size?: string | undefined; | ||
| readonly quality?: "low" | "medium" | "high" | "auto" | undefined; | ||
| readonly background?: "auto" | "opaque" | "transparent" | undefined; | ||
| readonly output_format?: "png" | "jpeg" | "webp" | undefined; | ||
| readonly output_compression?: number | undefined; | ||
| readonly action?: "generate" | "auto" | "edit" | undefined; | ||
| readonly background?: "auto" | "opaque" | "transparent" | undefined; | ||
| readonly input_fidelity?: "low" | "high" | undefined; | ||
| readonly partial_images?: number | undefined; | ||
| readonly quality?: "low" | "medium" | "high" | "auto" | undefined; | ||
| readonly size?: string | undefined; | ||
| })[] | undefined; | ||
@@ -410,10 +410,10 @@ readonly temperature?: number | undefined; | ||
| readonly type: "image_generation"; | ||
| readonly size?: string | undefined; | ||
| readonly quality?: "low" | "medium" | "high" | "auto" | undefined; | ||
| readonly background?: "auto" | "opaque" | "transparent" | undefined; | ||
| readonly output_format?: "png" | "jpeg" | "webp" | undefined; | ||
| readonly output_compression?: number | undefined; | ||
| readonly action?: "generate" | "auto" | "edit" | undefined; | ||
| readonly background?: "auto" | "opaque" | "transparent" | undefined; | ||
| readonly input_fidelity?: "low" | "high" | undefined; | ||
| readonly partial_images?: number | undefined; | ||
| readonly quality?: "low" | "medium" | "high" | "auto" | undefined; | ||
| readonly size?: string | undefined; | ||
| })[] | undefined; | ||
@@ -500,10 +500,10 @@ readonly temperature?: number | undefined; | ||
| readonly type: "image_generation"; | ||
| readonly size?: string | undefined; | ||
| readonly quality?: "low" | "medium" | "high" | "auto" | undefined; | ||
| readonly background?: "auto" | "opaque" | "transparent" | undefined; | ||
| readonly output_format?: "png" | "jpeg" | "webp" | undefined; | ||
| readonly output_compression?: number | undefined; | ||
| readonly action?: "generate" | "auto" | "edit" | undefined; | ||
| readonly background?: "auto" | "opaque" | "transparent" | undefined; | ||
| readonly input_fidelity?: "low" | "high" | undefined; | ||
| readonly partial_images?: number | undefined; | ||
| readonly quality?: "low" | "medium" | "high" | "auto" | undefined; | ||
| readonly size?: string | undefined; | ||
| })[] | undefined; | ||
@@ -590,10 +590,10 @@ readonly temperature?: number | undefined; | ||
| readonly type: "image_generation"; | ||
| readonly size?: string | undefined; | ||
| readonly quality?: "low" | "medium" | "high" | "auto" | undefined; | ||
| readonly background?: "auto" | "opaque" | "transparent" | undefined; | ||
| readonly output_format?: "png" | "jpeg" | "webp" | undefined; | ||
| readonly output_compression?: number | undefined; | ||
| readonly action?: "generate" | "auto" | "edit" | undefined; | ||
| readonly background?: "auto" | "opaque" | "transparent" | undefined; | ||
| readonly input_fidelity?: "low" | "high" | undefined; | ||
| readonly partial_images?: number | undefined; | ||
| readonly quality?: "low" | "medium" | "high" | "auto" | undefined; | ||
| readonly size?: string | undefined; | ||
| })[] | undefined; | ||
@@ -680,10 +680,10 @@ readonly temperature?: number | undefined; | ||
| readonly type: "image_generation"; | ||
| readonly size?: string | undefined; | ||
| readonly quality?: "low" | "medium" | "high" | "auto" | undefined; | ||
| readonly background?: "auto" | "opaque" | "transparent" | undefined; | ||
| readonly output_format?: "png" | "jpeg" | "webp" | undefined; | ||
| readonly output_compression?: number | undefined; | ||
| readonly action?: "generate" | "auto" | "edit" | undefined; | ||
| readonly background?: "auto" | "opaque" | "transparent" | undefined; | ||
| readonly input_fidelity?: "low" | "high" | undefined; | ||
| readonly partial_images?: number | undefined; | ||
| readonly quality?: "low" | "medium" | "high" | "auto" | undefined; | ||
| readonly size?: string | undefined; | ||
| })[] | undefined; | ||
@@ -690,0 +690,0 @@ readonly temperature?: number | undefined; |
@@ -152,10 +152,10 @@ import { type AtLeastOne, type ProviderAuthOption } from "../route/auth-options"; | ||
| readonly type: "image_generation"; | ||
| readonly size?: string | undefined; | ||
| readonly quality?: "low" | "medium" | "high" | "auto" | undefined; | ||
| readonly background?: "auto" | "opaque" | "transparent" | undefined; | ||
| readonly output_format?: "png" | "jpeg" | "webp" | undefined; | ||
| readonly output_compression?: number | undefined; | ||
| readonly action?: "generate" | "auto" | "edit" | undefined; | ||
| readonly background?: "auto" | "opaque" | "transparent" | undefined; | ||
| readonly input_fidelity?: "low" | "high" | undefined; | ||
| readonly partial_images?: number | undefined; | ||
| readonly quality?: "low" | "medium" | "high" | "auto" | undefined; | ||
| readonly size?: string | undefined; | ||
| })[] | undefined; | ||
@@ -162,0 +162,0 @@ readonly temperature?: number | undefined; |
@@ -140,10 +140,10 @@ import { type ProviderAuthOption } from "../route/auth-options"; | ||
| readonly type: "image_generation"; | ||
| readonly size?: string | undefined; | ||
| readonly quality?: "low" | "medium" | "high" | "auto" | undefined; | ||
| readonly background?: "auto" | "opaque" | "transparent" | undefined; | ||
| readonly output_format?: "png" | "jpeg" | "webp" | undefined; | ||
| readonly output_compression?: number | undefined; | ||
| readonly action?: "generate" | "auto" | "edit" | undefined; | ||
| readonly background?: "auto" | "opaque" | "transparent" | undefined; | ||
| readonly input_fidelity?: "low" | "high" | undefined; | ||
| readonly partial_images?: number | undefined; | ||
| readonly quality?: "low" | "medium" | "high" | "auto" | undefined; | ||
| readonly size?: string | undefined; | ||
| })[] | undefined; | ||
@@ -150,0 +150,0 @@ readonly temperature?: number | undefined; |
@@ -84,10 +84,10 @@ import type { ProviderPackage } from "../provider-package"; | ||
| readonly type: "image_generation"; | ||
| readonly size?: string | undefined; | ||
| readonly quality?: "low" | "medium" | "high" | "auto" | undefined; | ||
| readonly background?: "auto" | "opaque" | "transparent" | undefined; | ||
| readonly output_format?: "png" | "jpeg" | "webp" | undefined; | ||
| readonly output_compression?: number | undefined; | ||
| readonly action?: "generate" | "auto" | "edit" | undefined; | ||
| readonly background?: "auto" | "opaque" | "transparent" | undefined; | ||
| readonly input_fidelity?: "low" | "high" | undefined; | ||
| readonly partial_images?: number | undefined; | ||
| readonly quality?: "low" | "medium" | "high" | "auto" | undefined; | ||
| readonly size?: string | undefined; | ||
| })[] | undefined; | ||
@@ -94,0 +94,0 @@ readonly temperature?: number | undefined; |
@@ -82,10 +82,10 @@ import type { ProviderPackage } from "../provider-package"; | ||
| readonly type: "image_generation"; | ||
| readonly size?: string | undefined; | ||
| readonly quality?: "low" | "medium" | "high" | "auto" | undefined; | ||
| readonly background?: "auto" | "opaque" | "transparent" | undefined; | ||
| readonly output_format?: "png" | "jpeg" | "webp" | undefined; | ||
| readonly output_compression?: number | undefined; | ||
| readonly action?: "generate" | "auto" | "edit" | undefined; | ||
| readonly background?: "auto" | "opaque" | "transparent" | undefined; | ||
| readonly input_fidelity?: "low" | "high" | undefined; | ||
| readonly partial_images?: number | undefined; | ||
| readonly quality?: "low" | "medium" | "high" | "auto" | undefined; | ||
| readonly size?: string | undefined; | ||
| })[] | undefined; | ||
@@ -92,0 +92,0 @@ readonly temperature?: number | undefined; |
@@ -6,3 +6,3 @@ import { type ProviderAuthOption } from "../route/auth-options"; | ||
| import { type OpenAIProviderOptionsInput } from "./openai-options"; | ||
| import { type OpenAIImageOptions } from "../protocols/openai-images"; | ||
| import { type OpenAIImageString } from "../protocols/openai-images"; | ||
| export type { OpenAIOptionsInput, OpenAIResponseIncludable } from "./openai-options"; | ||
@@ -139,10 +139,10 @@ export type { OpenAIImageOptions } from "../protocols/openai-images"; | ||
| readonly type: "image_generation"; | ||
| readonly size?: string | undefined; | ||
| readonly quality?: "low" | "medium" | "high" | "auto" | undefined; | ||
| readonly background?: "auto" | "opaque" | "transparent" | undefined; | ||
| readonly output_format?: "png" | "jpeg" | "webp" | undefined; | ||
| readonly output_compression?: number | undefined; | ||
| readonly action?: "generate" | "auto" | "edit" | undefined; | ||
| readonly background?: "auto" | "opaque" | "transparent" | undefined; | ||
| readonly input_fidelity?: "low" | "high" | undefined; | ||
| readonly partial_images?: number | undefined; | ||
| readonly quality?: "low" | "medium" | "high" | "auto" | undefined; | ||
| readonly size?: string | undefined; | ||
| })[] | undefined; | ||
@@ -228,10 +228,10 @@ readonly temperature?: number | undefined; | ||
| readonly type: "image_generation"; | ||
| readonly size?: string | undefined; | ||
| readonly quality?: "low" | "medium" | "high" | "auto" | undefined; | ||
| readonly background?: "auto" | "opaque" | "transparent" | undefined; | ||
| readonly output_format?: "png" | "jpeg" | "webp" | undefined; | ||
| readonly output_compression?: number | undefined; | ||
| readonly action?: "generate" | "auto" | "edit" | undefined; | ||
| readonly background?: "auto" | "opaque" | "transparent" | undefined; | ||
| readonly input_fidelity?: "low" | "high" | undefined; | ||
| readonly partial_images?: number | undefined; | ||
| readonly quality?: "low" | "medium" | "high" | "auto" | undefined; | ||
| readonly size?: string | undefined; | ||
| })[] | undefined; | ||
@@ -257,16 +257,12 @@ readonly temperature?: number | undefined; | ||
| readonly providerOptions?: OpenAIProviderOptionsInput; | ||
| readonly image?: ImageConfig; | ||
| }; | ||
| export interface ImageConfig { | ||
| readonly providerOptions?: OpenAIImageOptions; | ||
| } | ||
| export interface ImageGenerationOptions { | ||
| readonly action?: "auto" | "generate" | "edit"; | ||
| readonly background?: "auto" | "opaque" | "transparent"; | ||
| readonly inputFidelity?: "low" | "high"; | ||
| readonly action?: OpenAIImageString<"auto" | "generate" | "edit">; | ||
| readonly background?: OpenAIImageString<"auto" | "opaque" | "transparent">; | ||
| readonly inputFidelity?: OpenAIImageString<"low" | "high">; | ||
| readonly outputCompression?: number; | ||
| readonly outputFormat?: "png" | "jpeg" | "webp"; | ||
| readonly outputFormat?: OpenAIImageString<"png" | "jpeg" | "webp">; | ||
| readonly partialImages?: number; | ||
| readonly quality?: "auto" | "low" | "medium" | "high"; | ||
| readonly size?: string; | ||
| readonly quality?: OpenAIImageString<"auto" | "low" | "medium" | "high" | "standard" | "hd">; | ||
| readonly size?: OpenAIImageString<"auto" | "256x256" | "512x512" | "1024x1024" | "1536x1024" | "1024x1536" | "1792x1024" | "1024x1792">; | ||
| } | ||
@@ -289,3 +285,3 @@ export declare const imageGeneration: (options?: ImageGenerationOptions) => ToolDefinition; | ||
| chat: (id: string | ModelID) => import("..").Model; | ||
| image: (modelID: string | ModelID) => import("..").ImageModel; | ||
| image: (modelID: string | ModelID) => import("..").ImageModel<import("./openai").OpenAIImageOptions>; | ||
| configure: (input?: Config) => /*elided*/ any; | ||
@@ -299,3 +295,3 @@ }; | ||
| chat: (id: string | ModelID) => import("..").Model; | ||
| image: (modelID: string | ModelID) => import("..").ImageModel; | ||
| image: (modelID: string | ModelID) => import("..").ImageModel<import("./openai").OpenAIImageOptions>; | ||
| configure: (input?: Config) => { | ||
@@ -307,3 +303,3 @@ id: string & import("effect/Brand").Brand<"LLM.ProviderID">; | ||
| chat: (id: string | ModelID) => import("..").Model; | ||
| image: (modelID: string | ModelID) => import("..").ImageModel; | ||
| image: (modelID: string | ModelID) => import("..").ImageModel<import("./openai").OpenAIImageOptions>; | ||
| configure: /*elided*/ any; | ||
@@ -317,2 +313,2 @@ }; | ||
| export declare const chat: (id: string | ModelID) => import("..").Model; | ||
| export declare const image: (modelID: string | ModelID) => import("..").ImageModel; | ||
| export declare const image: (modelID: string | ModelID) => import("..").ImageModel<import("./openai").OpenAIImageOptions>; |
@@ -29,3 +29,3 @@ import { AuthOptions } from "../route/auth-options"; | ||
| const defaults = (input) => { | ||
| const { apiKey: _, auth: _auth, baseURL: _baseURL, queryParams: _queryParams, image: _image, ...rest } = input; | ||
| const { apiKey: _, auth: _auth, baseURL: _baseURL, queryParams: _queryParams, ...rest } = input; | ||
| return rest; | ||
@@ -50,6 +50,3 @@ }; | ||
| headers: input.headers, | ||
| defaults: { | ||
| providerOptions: input.image?.providerOptions === undefined ? undefined : { openai: { ...input.image.providerOptions } }, | ||
| http: mergeHttpOptions(input.http === undefined ? undefined : HttpOptions.make(input.http), input.queryParams === undefined ? undefined : new HttpOptions({ query: input.queryParams })), | ||
| }, | ||
| http: mergeHttpOptions(input.http === undefined ? undefined : HttpOptions.make(input.http), input.queryParams === undefined ? undefined : new HttpOptions({ query: input.queryParams })), | ||
| }); | ||
@@ -56,0 +53,0 @@ return { |
@@ -136,10 +136,10 @@ import { type ProviderAuthOption } from "../route/auth-options"; | ||
| readonly type: "image_generation"; | ||
| readonly size?: string | undefined; | ||
| readonly quality?: "low" | "medium" | "high" | "auto" | undefined; | ||
| readonly background?: "auto" | "opaque" | "transparent" | undefined; | ||
| readonly output_format?: "png" | "jpeg" | "webp" | undefined; | ||
| readonly output_compression?: number | undefined; | ||
| readonly action?: "generate" | "auto" | "edit" | undefined; | ||
| readonly background?: "auto" | "opaque" | "transparent" | undefined; | ||
| readonly input_fidelity?: "low" | "high" | undefined; | ||
| readonly partial_images?: number | undefined; | ||
| readonly quality?: "low" | "medium" | "high" | "auto" | undefined; | ||
| readonly size?: string | undefined; | ||
| })[] | undefined; | ||
@@ -146,0 +146,0 @@ readonly temperature?: number | undefined; |
+4
-4
| { | ||
| "$schema": "https://json.schemastore.org/package.json", | ||
| "version": "0.0.0-next-15898", | ||
| "version": "0.0.0-next-15903", | ||
| "name": "@opencode-ai/ai", | ||
@@ -10,3 +10,3 @@ "type": "module", | ||
| "test": "bun test --timeout 30000 --only-failures", | ||
| "typecheck": "tsgo --noEmit", | ||
| "typecheck": "tsgo --noEmit && tsgo --noEmit -p tsconfig.types.json", | ||
| "build": "tsc -p tsconfig.build.json" | ||
@@ -30,3 +30,3 @@ }, | ||
| "@effect/platform-node": "4.0.0-beta.98", | ||
| "@opencode-ai/http-recorder": "0.0.0-next-15898", | ||
| "@opencode-ai/http-recorder": "0.0.0-next-15903", | ||
| "@tsconfig/bun": "1.0.9", | ||
@@ -40,3 +40,3 @@ "@types/bun": "1.3.13", | ||
| "@smithy/util-utf8": "4.2.2", | ||
| "@opencode-ai/schema": "0.0.0-next-15898", | ||
| "@opencode-ai/schema": "0.0.0-next-15903", | ||
| "aws4fetch": "1.0.20", | ||
@@ -43,0 +43,0 @@ "effect": "4.0.0-beta.98", |
+21
-3
@@ -39,5 +39,9 @@ # @opencode-ai/ai | ||
| prompt: "A robot tending a rooftop garden", | ||
| count: 2, | ||
| size: { width: 1024, height: 1024 }, | ||
| providerOptions: { openai: { quality: "high", outputFormat: "webp" } }, | ||
| options: { | ||
| n: 2, | ||
| size: "1024x1024", | ||
| quality: "high", // inferred from the OpenAI image model | ||
| outputFormat: "webp", | ||
| future_option: true, // unknown native options pass through unchanged | ||
| }, | ||
| }) | ||
@@ -49,2 +53,16 @@ | ||
| Provider-native image options belong to each request. Raw `http.body` fields have final precedence over them: | ||
| ```ts | ||
| const model = OpenAI.configure({ apiKey }).image("gpt-image-2") | ||
| yield * | ||
| Image.generate({ | ||
| model, | ||
| prompt, | ||
| options: { quality: "medium" }, | ||
| http, | ||
| }) | ||
| ``` | ||
| Conversational image generation remains part of the LLM interaction. OpenAI Responses exposes it through its hosted image tool: | ||
@@ -51,0 +69,0 @@ |
URL strings
Supply chain riskPackage contains fragments of external URLs or IP addresses, which the package may be accessing at runtime.
URL strings
Supply chain riskPackage contains fragments of external URLs or IP addresses, which the package may be accessing at runtime.
252
7.69%971747
-0.17%20581
-0.32%+ Added
- Removed